├── .github ├── dependabot.yml └── workflows │ ├── dockerhubpublish.yml │ ├── dockerimage.yml │ ├── pypipublish.yml │ └── pythonpackage.yml ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── CONTRIBUTORS ├── HISTORY ├── ISSUE_TEMPLATE.md ├── LICENSE ├── MANIFEST.in ├── README.md ├── README_actions.md ├── README_pypi.md ├── README_workflows.md ├── setup.py ├── src ├── Dockerfile ├── ea │ ├── .gitignore │ ├── VERSION │ ├── __init__.py │ ├── libs │ │ ├── FileModels │ │ │ ├── GenericModel.py │ │ │ ├── TestConfig.py │ │ │ ├── TestData.py │ │ │ ├── TestPlan.py │ │ │ ├── TestResult.py │ │ │ ├── TestSuite.py │ │ │ ├── TestUnit.py │ │ │ └── __init__.py │ │ ├── Logger.py │ │ ├── NetLayerLib │ │ │ ├── ClientAgent.py │ │ │ ├── FifoCallBack.py │ │ │ ├── Messages.py │ │ │ ├── ServerAgent.py │ │ │ ├── TcpClient.py │ │ │ ├── TcpServer.py │ │ │ ├── TransactionManager.py │ │ │ ├── WebSocket.py │ │ │ └── __init__.py │ │ ├── PyXmlDict │ │ │ ├── Dict2Xml.py │ │ │ ├── Test.py │ │ │ ├── Xml2Dict.py │ │ │ └── __init__.py │ │ ├── Scheduler.py │ │ ├── Settings.py │ │ ├── __init__.py │ │ └── daemon.py │ ├── releasenotes.txt │ ├── scripts │ │ ├── __init__.py │ │ ├── certificate │ │ │ ├── ca.crt │ │ │ ├── ca.key │ │ │ ├── generate-ca-certifcate.sh │ │ │ └── generate-key.sh │ │ ├── crontab │ │ │ ├── cron.cleanup-locks │ │ │ └── cron.cleanup-testsresult │ │ ├── database │ │ │ ├── common_bdd.py │ │ │ ├── create_database.py │ │ │ ├── data_globals.json │ │ │ ├── data_projects.json │ │ │ ├── data_users.json │ │ │ ├── init_data.py │ │ │ └── init_sqlite3.py │ │ ├── helps │ │ │ ├── DocInspect.py │ │ │ └── generate_helps.py │ │ ├── iptables │ │ │ └── iptables.rules │ │ ├── reverseproxy │ │ │ └── extensiveautomation_api.conf │ │ ├── startup │ │ │ ├── svr.centos7 │ │ │ └── svr.centos8 │ │ └── swagger │ │ │ ├── admin_restapi.yaml │ │ │ ├── common_restapi.yaml │ │ │ ├── generate_yaml.py │ │ │ └── tester_restapi.yaml │ ├── server.py │ ├── servercontrols │ │ ├── CliFunctions.py │ │ ├── RestAdminFunctions.py │ │ ├── RestCommonFunctions.py │ │ ├── RestRessources.py │ │ ├── RestServerInterface.py │ │ ├── RestTesterFunctions.py │ │ └── __init__.py │ ├── serverengine │ │ ├── AgentsManager.py │ │ ├── AutomationServer.py │ │ ├── Context.py │ │ ├── DbManager.py │ │ ├── HelperManager.py │ │ ├── ProjectsManager.py │ │ ├── StorageDataAdapters.py │ │ ├── TaskManager.py │ │ ├── UsersManager.py │ │ ├── VariablesManager.py │ │ └── __init__.py │ ├── serverinterfaces │ │ ├── AgentServerInterface.py │ │ ├── EventServerInterface.py │ │ ├── TestServerInterface.py │ │ └── __init__.py │ ├── serverrepositories │ │ ├── RepoAdapters.py │ │ ├── RepoArchives.py │ │ ├── RepoManager.py │ │ ├── RepoPublic.py │ │ ├── RepoTests.py │ │ └── __init__.py │ ├── settings.ini │ ├── sutadapters │ │ └── __init__.py │ ├── test.ini │ ├── testcreatorlib │ │ ├── TestModel.py │ │ ├── TestModelCommon.py │ │ ├── TestModelDesign.py │ │ ├── TestModelSub.py │ │ └── __init__.py │ ├── testexecutorlib │ │ ├── TestAdapterLib.py │ │ ├── TestClientInterface.py │ │ ├── TestDataStorage.py │ │ ├── TestExecutorLib.py │ │ ├── TestInteropLib.py │ │ ├── TestLibraryLib.py │ │ ├── TestLoggerXml.py │ │ ├── TestOperatorsLib.py │ │ ├── TestPropertiesLib.py │ │ ├── TestReportingLib.py │ │ ├── TestSettings.py │ │ ├── TestTemplatesLib.py │ │ ├── TestValidatorsLib.py │ │ └── __init__.py │ └── var │ │ ├── __init__.py │ │ ├── data.db │ │ ├── documentations.dat │ │ ├── templates │ │ ├── adapter_header.tpl │ │ ├── basic_report.tpl │ │ ├── chart.bundle.min.2.1.4.js │ │ ├── design.tpl │ │ ├── png_failed.base64 │ │ ├── png_passed.base64 │ │ ├── png_undefined.base64 │ │ ├── report.tpl │ │ └── report_header.tpl │ │ └── tests │ │ └── 1 │ │ ├── actions │ │ ├── basic │ │ │ ├── helloworld.yml │ │ │ └── wait.yml │ │ ├── cache │ │ │ └── log.yml │ │ └── features │ │ │ ├── action_parameters.yml │ │ │ ├── action_steps.yml │ │ │ ├── cache.yml │ │ │ ├── descriptions.yml │ │ │ ├── globals.yml │ │ │ ├── operators.yml │ │ │ ├── parameters.yml │ │ │ ├── steps.yml │ │ │ ├── validators.yml │ │ │ └── wait.yml │ │ ├── deprecated │ │ ├── Samples │ │ │ ├── Framework_Automate │ │ │ │ ├── 001_Automate.tpx │ │ │ │ ├── 01_Automates_Callbacks.tux │ │ │ │ ├── 01_Start_Automate.tux │ │ │ │ ├── 01_Start_Automate2.tux │ │ │ │ └── 01_Stop_Automate.tux │ │ │ ├── Framework_Features │ │ │ │ ├── 001_All_features.tpx │ │ │ │ ├── 01_Adapters_Functions.tsx │ │ │ │ ├── 01_Basic_Reporting.tux │ │ │ │ ├── 01_Breakpoint.tsx │ │ │ │ ├── 01_Cache.tsx │ │ │ │ ├── 01_Dataset.tsx │ │ │ │ ├── 01_Descriptions.tsx │ │ │ │ ├── 01_Framework_Assistant.tux │ │ │ │ ├── 01_Inputs_Outputs.tsx │ │ │ │ ├── 01_Interact.tsx │ │ │ │ ├── 01_Interact_Assistant.tux │ │ │ │ ├── 01_Set Result.tsx │ │ │ │ ├── 01_Several_Testsuites.tsx │ │ │ │ ├── 01_Shared.tsx │ │ │ │ ├── 01_Special Characters.tsx │ │ │ │ ├── 01_Steps Definition.tsx │ │ │ │ ├── 01_TestCase Functions.tsx │ │ │ │ ├── 01_Test_Operators.tsx │ │ │ │ ├── 01_Test_Templates.tsx │ │ │ │ ├── 01_Test_Templates_Adapters.tsx │ │ │ │ └── 01_Test_Validators.tsx │ │ │ ├── Framework_Tests │ │ │ │ ├── 0001_testglobal.tgx │ │ │ │ ├── 001_testplan.tpx │ │ │ │ ├── 001_testplan_abort.tpx │ │ │ │ ├── 001_testplan_conditionnal.tpx │ │ │ │ ├── 001_testplan_overwrite_parameters.tpx │ │ │ │ ├── 01_testconfig.tcx │ │ │ │ ├── 01_testdata.tdx │ │ │ │ ├── 01_testdata_xml.tdx │ │ │ │ ├── 01_testsuite.tsx │ │ │ │ └── 01_testunit.tux │ │ │ └── Self Testing │ │ │ │ ├── 000_SSH_API.tpx │ │ │ │ ├── 001_REST_API_Basic_Auth.tpx │ │ │ │ └── 001_REST_API_Session_Auth.tpx │ │ └── Snippets │ │ │ ├── Cache │ │ │ ├── 01_Set_Cache.tux │ │ │ ├── 02_Log_Cache.tux │ │ │ ├── 03_Reset_Cache.tux │ │ │ ├── 04_Checking_Cache.tux │ │ │ └── 05_Delete_Cache.tux │ │ │ ├── Do │ │ │ ├── 01_Wait.tux │ │ │ ├── 02_Terminate.tux │ │ │ ├── 03_Initialize.tux │ │ │ ├── 04_Info.tux │ │ │ └── 05_Warning.tux │ │ │ ├── Generators │ │ │ ├── 01_Gen_Sha.tux │ │ │ ├── 02_Gen_Md5.tux │ │ │ ├── 03_Gen_Uuid.tux │ │ │ └── 04_Gen_Base64.tux │ │ │ ├── Protocols │ │ │ ├── 01_Send_SSH.tsx │ │ │ └── 02_Send_HTTP_CURL.tsx │ │ │ ├── UI │ │ │ ├── 01_Win_OpenApp.tux │ │ │ ├── 02_Win_CloseApp.tux │ │ │ ├── 03_OpenBrowser.tux │ │ │ ├── 04_CloseBrowser.tux │ │ │ ├── 05_MaximizeBrowser.tux │ │ │ └── 06_OpenBrowser_AndMaximize.tux │ │ │ └── Verify │ │ │ ├── 01_Check_XML.tux │ │ │ └── 02_Check_JSON.tux │ │ └── workflows │ │ ├── basic │ │ ├── helloworld.yml │ │ └── wait.yml │ │ └── features │ │ ├── restapi_projects.yml │ │ ├── restapi_session.yml │ │ ├── restapi_system.yml │ │ ├── restapi_tasks.yml │ │ ├── restapi_tests_files.yml │ │ ├── restapi_tests_run.yml │ │ ├── restapi_users.yml │ │ ├── restapi_variables.yml │ │ ├── testlibrary.yml │ │ └── workflow_conditions.yml ├── extensiveautomation.py ├── requirements.txt └── start.sh └── tests └── test_server.py /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "pip" 4 | directory: "./src/" 5 | schedule: 6 | interval: "weekly" 7 | -------------------------------------------------------------------------------- /.github/workflows/dockerhubpublish.yml: -------------------------------------------------------------------------------- 1 | name: Publish to DockerHub 2 | 3 | on: 4 | release: 5 | types: [published] 6 | 7 | jobs: 8 | release: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v3 12 | 13 | - name: Build the Docker image 14 | run: | 15 | docker build ./src --file ./src/Dockerfile -t extensiveautomation-server 16 | 17 | - name: Tag image 18 | run: | 19 | EA_VERSION=$(cat ./src/ea/VERSION) 20 | EA_NAME="extensiveautomation" 21 | docker tag ${EA_NAME}-server ${EA_NAME}/${EA_NAME}-server:${EA_VERSION} 22 | docker tag ${EA_NAME}-server ${EA_NAME}/${EA_NAME}-server:latest 23 | 24 | - name: Upload to DockerHub 25 | run: | 26 | docker login -u ${{ secrets.DOCKERHUB_LOGIN }} -p ${{ secrets.DOCKERHUB_PASSWORD }} 27 | EA_VERSION=$(cat ./src/ea/VERSION) 28 | EA_NAME="extensiveautomation" 29 | docker push ${EA_NAME}/${EA_NAME}-server:latest 30 | docker push ${EA_NAME}/${EA_NAME}-server:${EA_VERSION} 31 | -------------------------------------------------------------------------------- /.github/workflows/dockerimage.yml: -------------------------------------------------------------------------------- 1 | name: Docker Image 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | - unstable 8 | pull_request: 9 | branches: 10 | - master 11 | - unstable 12 | 13 | jobs: 14 | build: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@v3 18 | 19 | - name: Build the Docker image 20 | run: | 21 | # build image 22 | docker build ./src --file ./src/Dockerfile -t extensiveautomation-server 23 | 24 | - name: Start the container 25 | run: | 26 | # start the container 27 | docker run -d -p 8081:8081 -p 8082:8082 -p 8083:8083 --name=extensive-server extensiveautomation-server 28 | 29 | - name: Test the server 30 | run: | 31 | # install web plugin 32 | ea="extensiveautomation" 33 | es="extensive-server" 34 | docker exec ${es} wget https://github.com/${ea}/${ea}-plugin-web/archive/master.zip 35 | docker exec ${es} unzip master.zip 36 | docker exec ${es} cp -rf ${ea}-plugin-web-master/src/ea/sutadapters/WEB/ ea/sutadapters/ 37 | docker exec ${es} ls ea/sutadapters/ 38 | docker exec ${es} cp -rf ${ea}-plugin-web-master/src/ea/var/tests/1/ ea/var/tests/ 39 | docker exec ${es} ls ea/var/tests/1/ 40 | docker exec ${es} python ${ea}.py --install-adapter WEB 41 | # install python dependancies 42 | pip install requests 43 | # start to test the server 44 | python -u ./tests/test_server.py 45 | -------------------------------------------------------------------------------- /.github/workflows/pypipublish.yml: -------------------------------------------------------------------------------- 1 | name: Publish to PyPI 2 | 3 | on: 4 | release: 5 | types: [published] 6 | 7 | jobs: 8 | release: 9 | runs-on: ubuntu-latest 10 | environment: release 11 | permissions: 12 | id-token: write 13 | 14 | steps: 15 | - uses: actions/checkout@v4 16 | - name: Setup Python 17 | uses: actions/setup-python@v4 18 | with: 19 | python-version: "3.11" 20 | 21 | - name: Install dependencies 22 | run: | 23 | python -m pip install --upgrade pip 24 | pip install twine 25 | 26 | - name: Build Python package 27 | run: | 28 | python setup.py sdist 29 | 30 | - name: Publish package distributions to PyPI 31 | uses: pypa/gh-action-pypi-publish@release/v1 32 | -------------------------------------------------------------------------------- /.github/workflows/pythonpackage.yml: -------------------------------------------------------------------------------- 1 | name: Python Package 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | - unstable 8 | pull_request: 9 | branches: 10 | - master 11 | - unstable 12 | 13 | jobs: 14 | build: 15 | runs-on: ${{ matrix.os }} 16 | strategy: 17 | max-parallel: 4 18 | matrix: 19 | python-version: ["3.8", "3.9", "3.10", "3.11"] 20 | os: [ ubuntu-latest ] 21 | 22 | steps: 23 | - uses: actions/checkout@v3 24 | 25 | - name: Set up Python ${{ matrix.python-version }} and ${{ matrix.os }} 26 | uses: actions/setup-python@v2 27 | with: 28 | python-version: ${{ matrix.python-version }} 29 | 30 | - name: Install dependencies 31 | run: | 32 | python -m pip install --upgrade pip 33 | pip install -r ./src/requirements.txt 34 | 35 | - name: Lint with flake8 36 | run: | 37 | pip install flake8 38 | # stop the build if there are Python syntax errors or undefined names 39 | flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics 40 | # exit-zero treats all errors as warnings. 41 | flake8 . --count --exit-zero --max-complexity=100 --max-line-length=200 --statistics 42 | 43 | - name: Build and install the pypi package 44 | run: | 45 | # build 46 | python setup.py sdist 47 | # install 48 | PKG_VERSION=`cat src/ea/VERSION` 49 | pip install ./dist/extensiveautomation_server-${PKG_VERSION}.tar.gz 50 | 51 | - name: Start the server 52 | run: | 53 | # start the server 54 | extensiveautomation --start 55 | # status the server 56 | extensiveautomation --status 57 | # install plugin web 58 | pip install extensiveautomation_plugin_web 59 | # reload server configuration 60 | extensiveautomation --reload 61 | 62 | - name: Test the server 63 | run: | 64 | # start to test the server 65 | python -u ./tests/test_server.py 66 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at d.machard@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contributors are welcome on this project. 2 | 3 | You can contribute on different ways 4 | - write documentations 5 | - report issues 6 | - fix issues 7 | - add features 8 | 9 | Best practices to report a issue: 10 | - report one bug for one issue 11 | - description the issue and how to reproduce it 12 | - add server and client logs 13 | - add screenshots 14 | 15 | Best practices to add new feature 16 | - fork the project and make a pull request on the master branch 17 | - one feature per pull request 18 | 19 | Best practices to contribute on the documentations 20 | - contact me on this case -------------------------------------------------------------------------------- /CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | 37 | -------------------------------------------------------------------------------- /ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### description of the issue 2 | 3 | ### steps to reproduce the issue 4 | 5 | ### additionnals informations like versions, logs, screenshots 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2010-2021 Denis MACHARD 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. -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include README_pypi.md 2 | include src/ea/VERSION 3 | include src/ea/releasenotes.txt 4 | include src/ea/settings.ini 5 | include src/ea/test.ini 6 | include src/ea/var/data.db 7 | include src/ea/var/documentations.dat 8 | recursive-include src/ea/var/tests/1/actions/ * 9 | recursive-include src/ea/var/tests/1/workflows/ * 10 | recursive-include src/ea/var/tests/1/deprecated/ * 11 | recursive-include src/ea/var/templates/ * 12 | recursive-include src/ea/scripts/ * -------------------------------------------------------------------------------- /README_actions.md: -------------------------------------------------------------------------------- 1 | # Actions 2 | 3 | Documentations for default actions. 4 | 5 | An action is individual python code source with enriched parameters. 6 | 7 | ## Table of contents 8 | * [basic/helloworld.yml](#basichelloworldyml) 9 | * [basic/wait.yml](#basicwaityml) 10 | * [cache/log.yml](#cachelogyml) 11 | * [generator/random_string.yml](#generatorrandom_stringyml) 12 | * [generator/random_integer.yml](#generatorrandom_integeryml) 13 | 14 | ## basic/helloworld.yml 15 | 16 | This action shows how to write a simple action. 17 | A action is made up of two parts: 18 | - property parameters 19 | - python code 20 | Parameters can be read from the python code with the function `input`. 21 | 22 | 1. Write properties of your actions 23 | 24 | ```yaml 25 | properties: 26 | parameters: 27 | - name: msg 28 | value: hello world 29 | ``` 30 | 31 | 2. In the `python` part, you need to create a class inherit from `Action`. 32 | 33 | ```python 34 | class HelloWorld(Action): 35 | ``` 36 | 37 | 3. Create the `definition` function. 38 | The second line show how to get a parameter from properties and log-it. 39 | 40 | ```python 41 | def definition(self): 42 | self.info(input("msg"))) 43 | ``` 44 | 45 | 4. Finally, you must instanciate the class and call the `execute()` function: 46 | 47 | ```python 48 | HelloWorld().execute() 49 | ``` 50 | 51 | ## basic/wait.yml 52 | 53 | Do nothing during x second(s). 54 | 55 | Parameter(s): 56 | - duration: number of second to wait 57 | 58 | ## cache/log.yml 59 | 60 | Log entry from cache. 61 | 62 | Parameter(s): 63 | - key (integer): name of the entry to log 64 | 65 | ## generator/random_string.yml 66 | 67 | Generate a random string 68 | 69 | Parameter(s): 70 | - string-length (integer): number of characters 71 | - with-lower-case (boolean): generate using lower-case (a,b,...) 72 | - with-upper-case (boolean): generate using upper-case (A,B,...) 73 | - with-punctuation (boolean): generate using punctuation (!,?,...) 74 | - cache-key (string): name of the random string to save-it in the cache 75 | 76 | ## generator/random_integer.yml 77 | 78 | Generate a random integer 79 | 80 | Parameter(s): 81 | - min-interval (integer): minimun interval to generate the number 82 | - max-interval (integer): maximun interval to generate the number 83 | - cache-key (string): name of the random integer to save-it in the cache 84 | -------------------------------------------------------------------------------- /README_pypi.md: -------------------------------------------------------------------------------- 1 | 2 | | | | 3 | | ------------- | ------------- | 4 | | ExtensiveAutomation | Python automation server | 5 | | Copyright | Copyright (c) 2010-2021 Denis Machard | 6 | | License | MIT | 7 | | Homepage | https://www.extensiveautomation.org/ | 8 | | Docs | https://extensiveautomation.readthedocs.io/en/latest/ | 9 | | Github | https://github.com/ExtensiveAutomation | 10 | | Docker Hub | https://hub.docker.com/u/extensiveautomation | 11 | | PyPI | https://pypi.org/project/extensiveautomation-server/ | 12 | | Google Users | https://groups.google.com/group/extensive-automation-users | 13 | | Twitter | https://twitter.com/Extensive_Auto | 14 | | | | 15 | 16 | [**ExtensiveAutomation**](https://github.com/ExtensiveAutomation/extensiveautomation-server) enable you to create custom workflows to automate your project. 17 | - a workflow is the combination of differents actions. 18 | - an action is individual python code source with enriched parameters. 19 | 20 | ## Installation 21 | 22 | 1. Run the following command 23 | 24 | python3 -m pip install extensiveautomation_server 25 | 26 | 2. Type the following command on your shell to start the server 27 | 28 | extensiveautomation --start 29 | -------------------------------------------------------------------------------- /README_workflows.md: -------------------------------------------------------------------------------- 1 | # Workflows 2 | 3 | Documentations for default workflows. 4 | a workflow is the combination of differents [actions](https://github.com/ExtensiveAutomation/extensiveautomation-server/blob/master/README_actions.md#actions). 5 | 6 | ## Table of contents 7 | * [basic/helloworld.yml](#basichelloworldyml) 8 | * [basic/wait.yml](#basicwaityml) 9 | * [generator/random.yml](#generatorrandomyml) 10 | 11 | ## basic/helloworld.yml 12 | 13 | This workflow shows how to write a simple workflow with one action. 14 | A workflow is made up of two parts: 15 | - property parameters 16 | - actions list to execute 17 | 18 | Property parameters override the parameters on each actions if the name is the same. 19 | Conditions between actions can be defined too. 20 | 21 | 1. In the actions part, add the `description` of your action 22 | 23 | ```yaml 24 | actions: 25 | - description: HelloWorld 26 | ``` 27 | 28 | 2. Add the path of the action 29 | 30 | ```yaml 31 | file: Common:actions/basic/helloworld.yml 32 | ``` 33 | 34 | 3. Overwrite parameters (optional) 35 | 36 | ```yaml 37 | parameters: 38 | - name: msg 39 | value: Hola Mundo 40 | ``` 41 | 42 | ## basic/wait.yml 43 | 44 | This workflow shows how to call the `wait.yml` action by 45 | overriding the duration parameter. 46 | 47 | ## generator/random.yml 48 | 49 | This workflow shows how to call two actions one after the other 50 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # ------------------------------------------------------------------- 4 | # Copyright (c) 2010-2021 Denis Machard 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a copy 7 | # of this software and associated documentation files (the "Software"), to deal 8 | # in the Software without restriction, including without limitation the rights 9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | # copies of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | 13 | # The above copyright notice and this permission notice shall be included in all 14 | # copies or substantial portions of the Software. 15 | 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | # SOFTWARE. 23 | # ------------------------------------------------------------------- 24 | 25 | import setuptools 26 | 27 | with open("src/ea/VERSION", "r") as fh: 28 | VERSION = fh.read() 29 | 30 | with open("README_pypi.md", "r") as fh: 31 | LONG_DESCRIPTION = fh.read() 32 | 33 | KEYWORDS = ('extensiveautomation automation testautomation testing') 34 | 35 | setuptools.setup( 36 | name="extensiveautomation_server", 37 | version=VERSION, 38 | author="Denis MACHARD", 39 | author_email="d.machard@gmail.com", 40 | description="Open source automation framework", 41 | long_description=LONG_DESCRIPTION, 42 | long_description_content_type="text/markdown", 43 | url="https://www.extensiveautomation.org/", 44 | package_dir={'': 'src'}, 45 | packages=setuptools.find_packages('src'), 46 | include_package_data=True, 47 | platforms='any', 48 | keywords=KEYWORDS, 49 | classifiers=[ 50 | "License :: OSI Approved :: MIT License", 51 | "Programming Language :: Python :: 3", 52 | "Operating System :: OS Independent", 53 | "Topic :: Software Development :: Testing", 54 | "Topic :: Software Development :: Testing :: Acceptance" 55 | ], 56 | entry_points={'console_scripts': ['extensiveautomation = ea.server:cli']}, 57 | install_requires=[ 58 | "wrapt", 59 | "scandir", 60 | "pycnic", 61 | "lxml", 62 | "jsonpath_ng", 63 | "pyyaml" 64 | ] 65 | ) 66 | -------------------------------------------------------------------------------- /src/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.11.4-alpine3.18 2 | 3 | LABEL name="Extensive Automation" \ 4 | description="ExtensiveAutomation is a generic automation framework for integration, regression and end-to-end usages" \ 5 | url="https://github.com/ExtensiveAutomation" \ 6 | maintainer="d.machard@gmail.com" 7 | 8 | WORKDIR /home/extensive 9 | 10 | COPY . /home/extensive/ 11 | 12 | RUN true \ 13 | && adduser -D extensive \ 14 | && apk add --update --no-cache g++ make libxslt-dev curl \ 15 | && pip install --upgrade pip \ 16 | && pip install --no-cache-dir -r requirements.txt \ 17 | && apk del --no-cache g++ make \ 18 | && cd /home/extensive \ 19 | && chmod 755 start.sh \ 20 | && chown -R extensive:extensive /home/extensive \ 21 | && sed -i 's/python=.*/python=\/usr\/local\/bin\/python/' /home/extensive/ea/settings.ini \ 22 | && true 23 | 24 | USER extensive 25 | 26 | EXPOSE 8081/tcp 8082/tcp 8083/tcp 27 | 28 | ENTRYPOINT ["/home/extensive/start.sh"] 29 | -------------------------------------------------------------------------------- /src/ea/.gitignore: -------------------------------------------------------------------------------- 1 | # Python files 2 | *.pyc 3 | *.pyo 4 | 5 | # Logs files 6 | *.log 7 | *.lock 8 | *.snapshot -------------------------------------------------------------------------------- /src/ea/VERSION: -------------------------------------------------------------------------------- 1 | 22.3.0 2 | -------------------------------------------------------------------------------- /src/ea/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # ------------------------------------------------------------------- 4 | # Copyright (c) 2010-2021 Denis Machard 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a copy 7 | # of this software and associated documentation files (the "Software"), to deal 8 | # in the Software without restriction, including without limitation the rights 9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | # copies of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | 13 | # The above copyright notice and this permission notice shall be included in all 14 | # copies or substantial portions of the Software. 15 | 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | # SOFTWARE. 23 | # ------------------------------------------------------------------- 24 | -------------------------------------------------------------------------------- /src/ea/libs/FileModels/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ------------------------------------------------------------------- 5 | # Copyright (c) 2010-2021 Denis Machard 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | # 14 | # The above copyright notice and this permission notice shall be included in all 15 | # copies or substantial portions of the Software. 16 | # 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | # ------------------------------------------------------------------- 25 | 26 | """ 27 | Files models module 28 | """ 29 | -------------------------------------------------------------------------------- /src/ea/libs/NetLayerLib/FifoCallBack.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ------------------------------------------------------------------- 5 | # Copyright (c) 2010-2021 Denis Machard 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | # 14 | # The above copyright notice and this permission notice shall be included in all 15 | # copies or substantial portions of the Software. 16 | # 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | # ------------------------------------------------------------------- 25 | 26 | """ 27 | Fifo module with callback 28 | """ 29 | import sys 30 | import threading 31 | try: 32 | import Queue 33 | except ImportError: # support python 3 34 | import queue as Queue 35 | 36 | # unicode = str with python3 37 | if sys.version_info > (3,): 38 | unicode = str 39 | 40 | 41 | class FifoCallbackThread(threading.Thread): 42 | """ 43 | Fifo with callback and thread 44 | """ 45 | 46 | def __init__(self): 47 | """ 48 | Construct a fifo callback function thread 49 | """ 50 | threading.Thread.__init__(self) 51 | self.queue = Queue.Queue(0) # FIFO size is infinite 52 | self.running = True 53 | self.event = threading.Event() 54 | 55 | def putItem(self, callback): 56 | """ 57 | Adds callback in the queue 58 | 59 | @param callback: 60 | @type callback: 61 | """ 62 | self.queue.put(callback) 63 | self.event.set() 64 | 65 | def run(self): 66 | """ 67 | Main loop 68 | """ 69 | while self.running: 70 | self.event.wait() 71 | if self.running: 72 | while not self.queue.empty(): 73 | try: 74 | callback = self.queue.get(False) 75 | callback() 76 | except Queue.Empty: 77 | self.event.clear() 78 | except Exception: 79 | pass 80 | self.event.clear() 81 | self.event.clear() 82 | self.onStop() 83 | 84 | def onStop(self): 85 | """ 86 | On stop 87 | """ 88 | pass 89 | 90 | def stop(self): 91 | """ 92 | Stops the thread 93 | """ 94 | self.running = False 95 | self.event.set() 96 | -------------------------------------------------------------------------------- /src/ea/libs/NetLayerLib/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ------------------------------------------------------------------- 5 | # Copyright (c) 2010-2021 Denis Machard 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | # 14 | # The above copyright notice and this permission notice shall be included in all 15 | # copies or substantial portions of the Software. 16 | # 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | # ------------------------------------------------------------------- 25 | 26 | """ 27 | Network layer library 28 | """ 29 | -------------------------------------------------------------------------------- /src/ea/libs/PyXmlDict/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: UTF-8 -*- 3 | 4 | # ------------------------------------------------------------------- 5 | # Copyright (c) 2010-2021 Denis Machard 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | # 14 | # The above copyright notice and this permission notice shall be included in all 15 | # copies or substantial portions of the Software. 16 | # 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | # ------------------------------------------------------------------- 25 | 26 | """ 27 | This module provides a codec to convert 28 | * Python Dict to XML string 29 | * XML string to Python Dict 30 | 31 | @author: Denis Machard 32 | @date: 06/13/2010 33 | """ 34 | -------------------------------------------------------------------------------- /src/ea/libs/Settings.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ------------------------------------------------------------------- 5 | # Copyright (c) 2010-2021 Denis Machard 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | # 14 | # The above copyright notice and this permission notice shall be included in all 15 | # copies or substantial portions of the Software. 16 | # 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | # ------------------------------------------------------------------- 25 | 26 | import sys 27 | import os 28 | try: 29 | import ConfigParser 30 | except ImportError: # python3 support 31 | import configparser as ConfigParser 32 | 33 | # extract the main path of the package 34 | path = os.path.abspath(__file__) 35 | dir_path = os.path.dirname(path) 36 | new_dir_path = os.sep.join(dir_path.split(os.sep)[:-1]) 37 | 38 | DIR_EXEC = os.path.normpath("%s/" % new_dir_path) 39 | 40 | 41 | def getDirExec(): 42 | """ 43 | @return: 44 | @rtype: 45 | """ 46 | return DIR_EXEC 47 | 48 | 49 | def getVersion(path="./"): 50 | """ 51 | @return: 52 | @rtype: 53 | """ 54 | ver = 'undefined' 55 | try: 56 | vpath = '%s/%s/VERSION' % (getDirExec(), path) 57 | f = open(vpath) 58 | ver = f.read() 59 | f.close() 60 | except Exception as e: 61 | print("[getVersion] Unable to read version: " + str(e)) 62 | return ver.strip() 63 | 64 | 65 | def cfgFileIsPresent(path="./", cfgname='settings.ini'): 66 | """ 67 | New in 1.2.0, to fix issue 9 68 | 69 | @return: 70 | @rtype: boolean 71 | """ 72 | ret = False 73 | if os.path.isfile('%s/%s/%s' % (getDirExec(), path, cfgname)): 74 | ret = True 75 | return ret 76 | 77 | 78 | SETTINGS = None # singleton 79 | 80 | 81 | def getInt(section, key): 82 | """ 83 | """ 84 | val = SETTINGS.get(section, key) 85 | return int(val) 86 | 87 | 88 | def getBool(section, key): 89 | """ 90 | """ 91 | val = SETTINGS.getboolean(section, key) 92 | return val 93 | 94 | 95 | def get(section, key): 96 | """ 97 | """ 98 | val = SETTINGS.get(section, key) 99 | return val 100 | 101 | 102 | def set(section, key, value, path="./", cfgname='settings.ini'): 103 | """ 104 | Set value and write to file 105 | Be careful, comments are removed with this function 106 | """ 107 | SETTINGS.set(section, key, value) 108 | completePath = '%s/%s/%s' % (getDirExec(), path, cfgname) 109 | with open(completePath, 'w') as f: 110 | SETTINGS.write(f) 111 | 112 | 113 | def instance(): 114 | """ 115 | Returns the singleton 116 | 117 | @return: 118 | @rtype: 119 | """ 120 | return SETTINGS 121 | 122 | 123 | def initialize(path="./", cfgname='settings.ini'): 124 | """ 125 | Instance creation 126 | """ 127 | global SETTINGS 128 | SETTINGS = ConfigParser.ConfigParser() 129 | completePath = '%s/%s/%s' % (getDirExec(), path, cfgname) 130 | 131 | if cfgFileIsPresent(path, cfgname): 132 | SETTINGS.read(completePath) 133 | else: 134 | sys.stdout.write("config file %s doesn't exist\n" % completePath) 135 | 136 | 137 | def finalize(): 138 | """ 139 | Destruction of the singleton 140 | """ 141 | global SETTINGS 142 | if SETTINGS: 143 | SETTINGS = None 144 | -------------------------------------------------------------------------------- /src/ea/libs/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ------------------------------------------------------------------- 5 | # Copyright (c) 2010-2021 Denis Machard 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | # 14 | # The above copyright notice and this permission notice shall be included in all 15 | # copies or substantial portions of the Software. 16 | # 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | # ------------------------------------------------------------------- 25 | -------------------------------------------------------------------------------- /src/ea/releasenotes.txt: -------------------------------------------------------------------------------- 1 | 2 | 22.2.0 3 | Date: 11/05/2021 4 | What's new 5 | 1. (minor): update to MIT license 6 | 2. (minor): dockerfile - update to python3.9.5-alpine3.13 7 | 3. (minor): fix issue #23 - decode bytes properly -------------------------------------------------------------------------------- /src/ea/scripts/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ------------------------------------------------------------------- 5 | # Copyright (c) 2010-2021 Denis Machard 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | 14 | # The above copyright notice and this permission notice shall be included in all 15 | # copies or substantial portions of the Software. 16 | 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | # ------------------------------------------------------------------- 25 | 26 | """ 27 | Scripts 28 | """ 29 | -------------------------------------------------------------------------------- /src/ea/scripts/certificate/ca.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIID5TCCAs2gAwIBAgIJAM1syl2rXsUjMA0GCSqGSIb3DQEBCwUAMIGxMQswCQYD 3 | VQQGEwJGUjERMA8GA1UECBMIQ0FMVkFET1MxDTALBgNVBAcTBENBRU4xGTAXBgNV 4 | BAoTEEV4dGVuc2l2ZVRlc3RpbmcxHTAbBgNVBAsTFEV4dGVuc2l2ZVRlc3Rpbmcu 5 | T1JHMSIwIAYJKoZIhvcNAQkBFhNkLm1hY2hhcmRAZ21haWwuY29tMSIwIAYDVQQD 6 | ExlkZW1vLmV4dGVuc2l2ZXRlc3Rpbmcub3JnMB4XDTE3MDYwMjIwMDUwNVoXDTE5 7 | MDYwMjIwMDUwNVowgbExCzAJBgNVBAYTAkZSMREwDwYDVQQIEwhDQUxWQURPUzEN 8 | MAsGA1UEBxMEQ0FFTjEZMBcGA1UEChMQRXh0ZW5zaXZlVGVzdGluZzEdMBsGA1UE 9 | CxMURXh0ZW5zaXZlVGVzdGluZy5PUkcxIjAgBgkqhkiG9w0BCQEWE2QubWFjaGFy 10 | ZEBnbWFpbC5jb20xIjAgBgNVBAMTGWRlbW8uZXh0ZW5zaXZldGVzdGluZy5vcmcw 11 | ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCWdG4xwb1EaWxtnl3YQNeH 12 | rN7+OqL4PgNzKZd3QpHH9qrkmy6Ior7a4UDfN8/YtxvI5cLUgVS8p7mMiXfCX9fk 13 | 6EvRZ6oWGMa9yLmxUPvjP4IFQBZsBgQZNxWUau13DYg6pgfq0MQjCOdcvqatQ2Xm 14 | T5J5S74mi3+65aJjr99G2biZFScOC5HJMuc3PL6PvsBxs8Cw/275L9NQ6sGNkI4B 15 | JPsPJditNY8MVAEGWdsvR/EtQo//d2RKybCFdiyUgp9sQ/MT2I3g1mopr8JPWcVt 16 | QVErfRtPBTxJC3FVTbuykdUWQDUSbx3/UyUbzX6iRtacYe9o2MMvm41c6MYstQvB 17 | AgMBAAEwDQYJKoZIhvcNAQELBQADggEBAIvgP4gdXDNL0tvEdfQzM1emQVRKo+sE 18 | jzSIsKrUSxPsfNIhhC63WhkzaQGh7iEZF7gj//ZxZMNiVr/5rmzc/PIIqc7W+8Zv 19 | y3UY3Taiwlgq/yWlOgm+seQ12XbZFlDVL3rgzYUApdtRMKwLD3nRIHfwoGxCM6VM 20 | Tqc04s+1Wpz9Fx7tF3/4ZLNT0+CUxeNjhUiFA9jVA22FkssWLU9JSBLWdspTbW5x 21 | sPVwBEwlBrapsoMLf89u3yO7nmgv3G5pxyDH3GDUMi5o4J3vBa5kLI72U+OzpQti 22 | GCPloF/wNDyiGi9lMU/dReHfL3nQKVjD2lstkP5SieHHymBK+hDmATc= 23 | -----END CERTIFICATE----- 24 | -------------------------------------------------------------------------------- /src/ea/scripts/certificate/ca.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEugIBADANBgkqhkiG9w0BAQEFAASCBKQwggSgAgEAAoIBAQCWdG4xwb1EaWxt 3 | nl3YQNeHrN7+OqL4PgNzKZd3QpHH9qrkmy6Ior7a4UDfN8/YtxvI5cLUgVS8p7mM 4 | iXfCX9fk6EvRZ6oWGMa9yLmxUPvjP4IFQBZsBgQZNxWUau13DYg6pgfq0MQjCOdc 5 | vqatQ2XmT5J5S74mi3+65aJjr99G2biZFScOC5HJMuc3PL6PvsBxs8Cw/275L9NQ 6 | 6sGNkI4BJPsPJditNY8MVAEGWdsvR/EtQo//d2RKybCFdiyUgp9sQ/MT2I3g1mop 7 | r8JPWcVtQVErfRtPBTxJC3FVTbuykdUWQDUSbx3/UyUbzX6iRtacYe9o2MMvm41c 8 | 6MYstQvBAgMBAAECgf8YrwFlKGPk1Wb0lQbQc9Lob3QmQXh7QbFPM4OmDUXdiJqA 9 | 5vS7dffZ8RqzhHSVGXV1gDx2oMFGMj4+0E7VlOPWqkXGFTvSZD425LeSX7bzkXfD 10 | ZMBI+LOzb1YbA2/yGEZBWPvzikyjctKCZMTzqBsPrf5Z6BNKP5i1EPeTY0c+WDmK 11 | Ksk4fLqTRUm7kCKgM1fSPqXTLp0SbUg5GEjVI1Db/4LbtS8/GN3gJQv+hRIDqVWJ 12 | 9uyRTERfHyIUi4jhlKqK8JfPui7LXpZUy/Ue4JWjB8TGHdlKEDDoX705XJwohB+J 13 | jhsSqzzIL057iTYGYQBcT9/IjOYgsS90PL1qkikCgYEAxqebpr0TDOqSaQ/mj/Xg 14 | WecP/JcKSvYy361bcE/swVbCMpEfz593b63c7X7k5YOQb/5h/+42afSzpRF1ZeIv 15 | dkXnL+jU4kSZimxXVWpNvsZsHxcpbp++DyTHP5ZnPliCQff1uPTd/uK0yAMHx0no 16 | MYEvvL/SDiMDDnB6a5ACMKcCgYEAweLlOuevryfF5cCgIUJ9ERM/Yicva5sfXWRP 17 | RX4czK6RSV42iVUrJaFxdDTDzdgEnnAasWU74/hJ012VaKuGrn4Y4ykP5WIDsM1K 18 | eZbQ3vJSuV4rTsgx9nYn3tzC7f3dGONMqQynnF0Xuo2KoaQDDlAkk5o/gCd4HII8 19 | aOoKxVcCgYAaLvFHEti19R0DGANtqhy9/MSQqF/E7Zpa/QB2VzJ/cS37eEFXHk+h 20 | uqrJ6tXEooihGkhUcVNet9ANy7VLjnpu/luwZuHYSO5r3kfMjExe/sw1dNoTKJ7m 21 | ZBSW/v3wq73PcB1FGZFBDSSC0FNwIv+ltr9SA35uOpMmjhC0qLCBNQKBgB4qxInu 22 | xJoXMSZ3WzLxmm4OtZz7BdjTUQUB94eTgL2kJ7znqMqjcswvG2z+TLz5cHaKcMzL 23 | OI9W8X2uoPGhRppdyleF6xBAuNxIhN74RVV7FL381fYzFfsIFVoKtVW8WytlKmdf 24 | LbEZlviSz1ApKcSPWbGRnXG+MmUVKnsUd0qPAoGARqfwkWTpZUWChJoyX5T9L6FX 25 | 9EOejgxsDMOEmsPbsjUz397f2IuBPQHKCMLBe4kGhXLjLYnQc1HBl5ygTwHZ1Qgk 26 | vYPnvIMXPxsp/PJplYRXv3g9JqFRu0ALAa5dr3deC2yvccJbd7AH1GuNNEhLHltq 27 | 3xHDzNvSjGcchdi4LR8= 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /src/ea/scripts/certificate/generate-ca-certifcate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # ------------------------------------------------------------------- 4 | # Copyright (c) 2010-2021 Denis Machard 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a copy 7 | # of this software and associated documentation files (the "Software"), to deal 8 | # in the Software without restriction, including without limitation the rights 9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | # copies of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in all 14 | # copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | # SOFTWARE. 23 | # ------------------------------------------------------------------- 24 | 25 | # Generate private key and gGenerate CSR 26 | cat > csr_details.txt <<-EOF 27 | [req] 28 | default_bits = 2048 29 | prompt = no 30 | default_md = sha256 31 | req_extensions = req_ext 32 | distinguished_name = dn 33 | 34 | [ dn ] 35 | C=FR 36 | ST=CALVADOS 37 | L=CAEN 38 | O=ExtensiveAutomation 39 | OU=ExtensiveAutomation.org 40 | emailAddress=d.machard@gmail.com 41 | CN=demo.extensiveautomation.org 42 | 43 | [ req_ext ] 44 | subjectAltName = @alt_names 45 | 46 | [ alt_names ] 47 | DNS.1 = www.extensiveautomation.org 48 | DNS.2 = www.extensive-automation.org 49 | DNS.3 = demo.extensive-automation.org 50 | EOF 51 | openssl req -new -nodes -sha256 -out ca.csr -newkey rsa:2048 -keyout ca.key -extensions req_ext -config <( cat csr_details.txt ) 52 | 53 | # Generate Self Signed Key 54 | openssl x509 -req -sha256 -days 730 -in ca.csr -signkey ca.key -out ca.crt -extfile <( cat csr_details.txt ) 55 | 56 | # Remove CSR 57 | rm -rf ca.csr 58 | rm -rf csr_details.txt 59 | -------------------------------------------------------------------------------- /src/ea/scripts/certificate/generate-key.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # ------------------------------------------------------------------- 4 | # Copyright (c) 2010-2021 Denis Machard 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a copy 7 | # of this software and associated documentation files (the "Software"), to deal 8 | # in the Software without restriction, including without limitation the rights 9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | # copies of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in all 14 | # copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | # SOFTWARE. 23 | # ------------------------------------------------------------------- 24 | 25 | APP_NAME="extensiveautomation" 26 | 27 | # For 256-bit key: 28 | openssl enc -aes-256-cbc -P -md md5 > $APP_NAME.key -------------------------------------------------------------------------------- /src/ea/scripts/crontab/cron.cleanup-locks: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # ------------------------------------------------------------------- 4 | # Copyright (c) 2010-2021 Denis Machard 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a copy 7 | # of this software and associated documentation files (the "Software"), to deal 8 | # in the Software without restriction, including without limitation the rights 9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | # copies of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | 13 | # The above copyright notice and this permission notice shall be included in all 14 | # copies or substantial portions of the Software. 15 | 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | # SOFTWARE. 23 | # ------------------------------------------------------------------- 24 | 25 | INSTALL_PATH=../../ 26 | 27 | 28 | echo "- clean lock files in adapters" 29 | find $INSTALL_PATH/var/sutadapters/. -name "*.lock" -exec rm -rf {} \; 30 | 31 | echo "- clean lock files in tests" 32 | find $INSTALL_PATH/var/tests/. -name "*.lock" -exec rm -rf {} \; 33 | -------------------------------------------------------------------------------- /src/ea/scripts/crontab/cron.cleanup-testsresult: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # ------------------------------------------------------------------- 4 | # Copyright (c) 2010-2021 Denis Machard 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a copy 7 | # of this software and associated documentation files (the "Software"), to deal 8 | # in the Software without restriction, including without limitation the rights 9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | # copies of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | 13 | # The above copyright notice and this permission notice shall be included in all 14 | # copies or substantial portions of the Software. 15 | 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | # SOFTWARE. 23 | # ------------------------------------------------------------------- 24 | 25 | # delete archives backups older than XX days 26 | # put this file in /etc/cron.weekly/ 27 | 28 | # nb days 29 | OLDER_THAN=30 30 | INSTALL_PATH= 31 | FIND_BIN=/usr/bin/find 32 | 33 | # delete tests results 34 | $FIND_BIN $INSTALL_PATH/var/testsresult/* -maxdepth 1 -type d -ctime +$OLDER_THAN -exec rm -rf {} \; 35 | 36 | # delete empty directories 37 | $FIND_BIN $INSTALL_PATH/var/testsresult/ -type d -empty -delete 38 | -------------------------------------------------------------------------------- /src/ea/scripts/database/common_bdd.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ------------------------------------------------------------------- 5 | # Copyright (c) 2010-2021 Denis Machard 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | 14 | # The above copyright notice and this permission notice shall be included in all 15 | # copies or substantial portions of the Software. 16 | 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | # ------------------------------------------------------------------- 25 | 26 | import os 27 | import sqlite3 28 | 29 | path = os.path.abspath(__file__) 30 | dir_path = os.path.dirname(path) 31 | new_dir_path = os.sep.join(dir_path.split(os.sep)[:-2]) 32 | 33 | DIR_EXEC = os.path.normpath("%s/" % new_dir_path) 34 | 35 | # prepare the path of the database 36 | db_name = "%s/var/data.db" % (DIR_EXEC) 37 | 38 | 39 | def delete_db(): 40 | """ 41 | """ 42 | print("Removing current database...") 43 | try: 44 | os.remove(db_name) 45 | except Exception: 46 | pass 47 | 48 | 49 | def querySQL(query): 50 | """ 51 | detect dabatase type 52 | only 2 type supported (mysql and sqlite) 53 | 54 | @param query: sql query 55 | @type query: string 56 | """ 57 | # connect to the db 58 | conn = sqlite3.connect(db_name) 59 | 60 | c = conn.cursor() 61 | 62 | # execute the sql query 63 | print(query) 64 | print() 65 | c.execute(query) 66 | 67 | # retrieve the last id 68 | lastrowid = c.lastrowid 69 | 70 | c.close() 71 | 72 | conn.commit() 73 | conn.close() 74 | 75 | return lastrowid 76 | -------------------------------------------------------------------------------- /src/ea/scripts/database/create_database.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ------------------------------------------------------------------- 5 | # Copyright (c) 2010-2021 Denis Machard 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | 14 | # The above copyright notice and this permission notice shall be included in all 15 | # copies or substantial portions of the Software. 16 | 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | # ------------------------------------------------------------------- 25 | 26 | from init_sqlite3 import create_sqlite3_model 27 | from common_bdd import delete_db 28 | 29 | from init_data import add_configs 30 | from init_data import add_users 31 | from init_data import add_projects 32 | from init_data import add_globals 33 | 34 | # remove the current database 35 | delete_db() 36 | 37 | # create a new one with model 38 | create_sqlite3_model() 39 | 40 | # populate the database with default datas 41 | cfg = add_configs() 42 | add_projects() 43 | add_users(auth_salt=cfg["auth-salt"]) 44 | add_globals() 45 | -------------------------------------------------------------------------------- /src/ea/scripts/database/data_globals.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "DEBUG", 4 | "value": false, 5 | "project-id": 1 6 | }, 7 | { 8 | "name": "TIMEOUT", 9 | "value": 1.0, 10 | "project-id": 1 11 | }, 12 | { 13 | "name": "SAMPLE_NODE", 14 | "value": { 15 | "SSH_ADMIN": { 16 | "SSH_AGENT_SUPPORT": false, 17 | "SSH_DEST_PORT": 22, 18 | "SSH_AGENT": { 19 | "type": "ssh", 20 | "name": "agent.ssh01" 21 | }, 22 | "SSH_PRIVATE_KEY": null, 23 | "SSH_PRIVATE_KEY_PATH": null, 24 | "SSH_DEST_PWD": "", 25 | "SSH_DEST_LOGIN": "root", 26 | "SSH_DEST_HOST": "127.0.0.1" 27 | }, 28 | "REST_API": { 29 | "HTTP_BASE_PATH": "/rest", 30 | "HTTP_DEST_PORT": 443, 31 | "HTTP_AGENT_SUPPORT": false, 32 | "HTTP_DEST_HOST": "127.0.0.1", 33 | "HTTP_AGENT": { 34 | "type": "socket", 35 | "name": "agent.socket01" 36 | }, 37 | "HTTP_HOSTNAME": "www.extensiveautomation.org", 38 | "HTTP_DEST_SSL": true 39 | } 40 | }, 41 | "project-id": 1 42 | }, 43 | { 44 | "name": "SAMPLE_DATA", 45 | "value": { 46 | "PROJECT": { 47 | "name": "auto", 48 | "name_new": "auto-updated" 49 | }, 50 | "TEST": { 51 | "dir_name": "auto", 52 | "project_name": "Common", 53 | "test_path": "/Snippets/Do/01_Wait.tux" 54 | }, 55 | "VARIABLE": { 56 | "variable_value": "1.0", 57 | "project_name": "Common", 58 | "variable_name": "VAR_AUTO" 59 | }, 60 | "USER": { 61 | "password_new": "auto_new", 62 | "email_new": "new@world.test", 63 | "password": "", 64 | "login": "auto", 65 | "email": "hello@world.test" 66 | }, 67 | "AUTH": { 68 | "login": "admin", 69 | "password": "password" 70 | } 71 | }, 72 | "project-id": 1 73 | } 74 | ] -------------------------------------------------------------------------------- /src/ea/scripts/database/data_projects.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": 1, 4 | "name": "Common" 5 | } 6 | ] -------------------------------------------------------------------------------- /src/ea/scripts/database/data_users.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "login": "admin", 4 | "password": "password", 5 | "email": "admin@localhost", 6 | "level": "administrator", 7 | "default-project": 1, 8 | "projects": [ 1 ] 9 | }, 10 | { 11 | "login": "monitor", 12 | "password": "password", 13 | "email": "monitor@localhost", 14 | "level": "monitor", 15 | "default-project": 1, 16 | "projects": [ 1 ] 17 | }, 18 | { 19 | "login": "tester", 20 | "password": "password", 21 | "email": "tester@localhost", 22 | "level": "tester", 23 | "default-project": 1, 24 | "projects": [ 1 ] 25 | } 26 | ] 27 | -------------------------------------------------------------------------------- /src/ea/scripts/database/init_sqlite3.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ------------------------------------------------------------------- 5 | # Copyright (c) 2010-2021 Denis Machard 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | 14 | # The above copyright notice and this permission notice shall be included in all 15 | # copies or substantial portions of the Software. 16 | 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | # ------------------------------------------------------------------- 25 | 26 | from common_bdd import querySQL 27 | 28 | 29 | def create_sqlite3_model(): 30 | print("Initializing new database...") 31 | print() 32 | 33 | querySQL(query="CREATE TABLE `users` (\ 34 | `id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, \ 35 | `login` varchar(50) NOT NULL, \ 36 | `password` varchar(200) NOT NULL, \ 37 | `administrator` INT, \ 38 | `monitor` INT, \ 39 | `tester` INT, \ 40 | `email` varchar(200) NOT NULL, \ 41 | `lang` varchar(50) NOT NULL, \ 42 | `style` varchar(50) NOT NULL, \ 43 | `active` INT, \ 44 | `online` INT, \ 45 | `notifications` varchar(200) NOT NULL, \ 46 | `defaultproject` INT, \ 47 | `apikey_id` varchar(200), \ 48 | `apikey_secret` varchar(200) \ 49 | );") 50 | 51 | querySQL(query="CREATE TABLE `tasks-history` (\ 52 | `id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, \ 53 | `eventtype` INT not null, \ 54 | `eventargs` VARCHAR(50), \ 55 | `eventtime` VARCHAR(20), \ 56 | `eventname` VARCHAR(200), \ 57 | `eventauthor` VARCHAR(50), \ 58 | `realruntime` VARCHAR(20), \ 59 | `eventduration` VARCHAR(20), \ 60 | `eventresult` VARCHAR(20), \ 61 | `projectid` INT \ 62 | ) ;") 63 | 64 | querySQL(query="CREATE TABLE `config` (\ 65 | `id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, \ 66 | `opt` TEXT, \ 67 | `value` TEXT \ 68 | );") 69 | 70 | querySQL(query="CREATE TABLE `projects` (\ 71 | `id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, \ 72 | `name` TEXT, \ 73 | `active` INT, \ 74 | `description` TEXT \ 75 | );") 76 | 77 | querySQL(query="CREATE TABLE `relations-projects` (\ 78 | `id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, \ 79 | `user_id` INT, \ 80 | `project_id` INT \ 81 | );") 82 | 83 | querySQL(query="CREATE TABLE `test-environment` (\ 84 | `id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, \ 85 | `name` TEXT, \ 86 | `value` TEXT, \ 87 | `project_id` INT \ 88 | );") 89 | 90 | querySQL(query="CREATE TABLE `agents` (\ 91 | `id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, \ 92 | `token` INT, \ 93 | `name` varchar(50) NOT NULL, \ 94 | `project_id` INT \ 95 | );") -------------------------------------------------------------------------------- /src/ea/scripts/iptables/iptables.rules: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # ------------------------------------------------------------------- 4 | # Copyright (c) 2010-2021 Denis Machard 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a copy 7 | # of this software and associated documentation files (the "Software"), to deal 8 | # in the Software without restriction, including without limitation the rights 9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | # copies of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | 13 | # The above copyright notice and this permission notice shall be included in all 14 | # copies or substantial portions of the Software. 15 | 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | # SOFTWARE. 23 | # ------------------------------------------------------------------- 24 | 25 | # Flush all current rules from iptables 26 | iptables -F 27 | 28 | # Allow SSH connections on tcp port 22 29 | iptables -A INPUT -p tcp --dport 22 -j ACCEPT 30 | 31 | # Allow test server connections on tcp port (rest api, event api) 32 | iptables -A INPUT -p tcp --dport 8081 -j ACCEPT 33 | iptables -A INPUT -p tcp --dport 8082 -j ACCEPT 34 | 35 | # Allow test server connections on tcp port (agents interfaces) 36 | iptables -A INPUT -p tcp --dport 8083 -j ACCEPT 37 | 38 | # Set default policies for INPUT, FORWARD and OUTPUT chains 39 | iptables -P INPUT DROP 40 | iptables -P FORWARD DROP 41 | iptables -P OUTPUT ACCEPT 42 | 43 | # Set access for localhost 44 | iptables -A INPUT -i lo -j ACCEPT 45 | 46 | # Accept packets belonging to established and related connections 47 | iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT 48 | 49 | # Save settings 50 | iptables save 51 | 52 | # List rules 53 | iptables -L -v -------------------------------------------------------------------------------- /src/ea/scripts/reverseproxy/extensiveautomation_api.conf: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------------- 2 | # Copyright (c) 2010-2021 Denis Machard 3 | # 4 | # Permission is hereby granted, free of charge, to any person obtaining a copy 5 | # of this software and associated documentation files (the "Software"), to deal 6 | # in the Software without restriction, including without limitation the rights 7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | # copies of the Software, and to permit persons to whom the Software is 9 | # furnished to do so, subject to the following conditions: 10 | 11 | # The above copyright notice and this permission notice shall be included in all 12 | # copies or substantial portions of the Software. 13 | 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | # SOFTWARE. 21 | # ------------------------------------------------------------------- 22 | 23 | ServerSignature Off 24 | ServerTokens Full 25 | 26 | Listen 8080 27 | 28 | 29 | SSLEngine on 30 | 31 | SSLCertificateFile /etc/pki/tls/certs/localhost.crt 32 | SSLCertificateKeyFile /etc/pki/tls/private/localhost.key 33 | 34 | LogLevel warn 35 | ErrorLog /var/log/extensiveautomation_api_error_ssl_rp.log 36 | CustomLog /var/log/extensiveautomation_api_access_ssl_rp.log combined 37 | 38 | Redirect 307 / /rest/session/login 39 | 40 | ProxyPass /rest/ http://127.0.0.1:8081/ 41 | ProxyPassReverse /rest/ http://127.0.0.1:8081/ 42 | 43 | ProxyPass /wss/client/ ws://127.0.0.1:8082 disablereuse=on 44 | ProxyPassReverse /wss/client/ ws://127.0.0.1:8082 disablereuse=on 45 | 46 | ProxyPass /wss/agent/ ws://127.0.0.1:8083 disablereuse=on 47 | ProxyPassReverse /wss/agent/ ws://127.0.0.1:8083 disablereuse=on 48 | 49 | 50 | -------------------------------------------------------------------------------- /src/ea/scripts/startup/svr.centos7: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Extensive Automation Service 3 | After=network.target 4 | 5 | [Service] 6 | Type=forking 7 | ExecStart=/opt/ea/extensiveautomation --start 8 | ExecStop=/opt/ea/extensiveautomation --stop 9 | ExecReload=/opt/ea/extensiveautomation --reload 10 | RemainAfterExit=yes 11 | User=root 12 | Group=root 13 | 14 | [Install] 15 | WantedBy=multi-user.target 16 | -------------------------------------------------------------------------------- /src/ea/scripts/startup/svr.centos8: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Extensive Automation Service 3 | After=network.target 4 | 5 | [Service] 6 | Type=forking 7 | ExecStart=/opt/ea/extensiveautomation --start 8 | ExecStop=/opt/ea/extensiveautomation --stop 9 | ExecReload=/opt/ea/extensiveautomation --reload 10 | RemainAfterExit=yes 11 | User=root 12 | Group=root 13 | 14 | [Install] 15 | WantedBy=multi-user.target 16 | -------------------------------------------------------------------------------- /src/ea/servercontrols/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ------------------------------------------------------------------- 5 | # Copyright (c) 2010-2021 Denis Machard 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | 14 | # The above copyright notice and this permission notice shall be included in all 15 | # copies or substantial portions of the Software. 16 | 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | # ------------------------------------------------------------------- 25 | -------------------------------------------------------------------------------- /src/ea/serverengine/AgentsManager.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ------------------------------------------------------------------- 5 | # Copyright (c) 2010-2021 Denis Machard 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | 14 | # The above copyright notice and this permission notice shall be included in all 15 | # copies or substantial portions of the Software. 16 | 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | # ------------------------------------------------------------------- 25 | 26 | from ea.libs import Logger 27 | from ea.serverinterfaces import AgentServerInterface as ASI 28 | 29 | from ea.serverengine import DbManager 30 | 31 | class AgentsManager(Logger.ClassLogger): 32 | def __init__(self, context): 33 | """ 34 | Construct Probes Manager 35 | """ 36 | self.context = context 37 | 38 | self.tb_agents = 'agents' 39 | # load agents token in cache, new in v23 40 | self.cache = {} 41 | self.load_cache() 42 | 43 | def load_cache(self): 44 | """load cache""" 45 | self.cache = {} 46 | 47 | sql = """SELECT * FROM `%s`""" % (self.tb_agents) 48 | success, rows = DbManager.instance().querySQL(query=sql, 49 | columnName=True) 50 | if not success: 51 | raise Exception("unable to init agents caching") 52 | 53 | for r in rows: 54 | self.cache[r["token"]] = r 55 | 56 | def getRunning(self, b64=False): 57 | """ 58 | Returns all registered agent 59 | """ 60 | self.trace("get running agents") 61 | ret = ASI.instance().getAgents() 62 | return ret 63 | 64 | def disconnectAgent(self, name): 65 | """ 66 | Disconnect agent 67 | """ 68 | self.info("Disconnect agent Name=%s" % name) 69 | if name not in ASI.instance().agentsRegistered: 70 | self.trace("disconnect agent, agent %s not found" % name) 71 | return self.context.CODE_NOT_FOUND 72 | 73 | agentProfile = ASI.instance().agentsRegistered[name] 74 | ASI.instance().stopClient(client=agentProfile['address']) 75 | return self.context.CODE_OK 76 | 77 | 78 | AM = None 79 | 80 | 81 | def instance(): 82 | """ 83 | Returns the singleton 84 | """ 85 | return AM 86 | 87 | 88 | def initialize(*args, **kwargs): 89 | """ 90 | Instance creation 91 | """ 92 | global AM 93 | AM = AgentsManager(*args, **kwargs) 94 | 95 | 96 | def finalize(): 97 | """ 98 | Destruction of the singleton 99 | """ 100 | global AM 101 | if AM: 102 | AM = None 103 | -------------------------------------------------------------------------------- /src/ea/serverengine/HelperManager.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ------------------------------------------------------------------- 5 | # Copyright (c) 2010-2021 Denis Machard 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | 14 | # The above copyright notice and this permission notice shall be included in all 15 | # copies or substantial portions of the Software. 16 | 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | # ------------------------------------------------------------------- 25 | 26 | import base64 27 | import zlib 28 | import os 29 | 30 | from ea.libs import Settings, Logger 31 | 32 | 33 | class HelperManager(Logger.ClassLogger): 34 | def getHelps(self): 35 | """ 36 | Returns the documentation cache 37 | """ 38 | self.trace("get helps") 39 | ret = '' 40 | try: 41 | complete_path = '%s/%s/documentations.dat' % (Settings.getDirExec(), 42 | Settings.get('Paths', 'var')) 43 | if os.path.exists(complete_path): 44 | fd = open(complete_path, "rb") 45 | data = fd.read() 46 | fd.close() 47 | 48 | ret = base64.b64encode(zlib.compress(data)) 49 | else: 50 | self.error('documentation cache does not exist') 51 | except Exception as e: 52 | self.error("unable to get helps: %s" % e) 53 | return ret.decode('utf8') 54 | 55 | 56 | HM = None # singleton 57 | 58 | 59 | def instance(): 60 | """ 61 | Returns the singleton 62 | """ 63 | return HM 64 | 65 | 66 | def initialize(): 67 | """ 68 | Instance creation 69 | """ 70 | global HM 71 | HM = HelperManager() 72 | 73 | 74 | def finalize(): 75 | """ 76 | Destruction of the singleton 77 | """ 78 | global HM 79 | if HM: 80 | HM = None 81 | -------------------------------------------------------------------------------- /src/ea/serverengine/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ------------------------------------------------------------------- 5 | # Copyright (c) 2010-2021 Denis Machard 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | 14 | # The above copyright notice and this permission notice shall be included in all 15 | # copies or substantial portions of the Software. 16 | 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | # ------------------------------------------------------------------- 25 | -------------------------------------------------------------------------------- /src/ea/serverinterfaces/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ------------------------------------------------------------------- 5 | # Copyright (c) 2010-2021 Denis Machard 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | 14 | # The above copyright notice and this permission notice shall be included in all 15 | # copies or substantial portions of the Software. 16 | 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | # ------------------------------------------------------------------- 25 | -------------------------------------------------------------------------------- /src/ea/serverrepositories/RepoPublic.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ------------------------------------------------------------------- 5 | # Copyright (c) 2010-2021 Denis Machard 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | 14 | # The above copyright notice and this permission notice shall be included in all 15 | # copies or substantial portions of the Software. 16 | 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | # ------------------------------------------------------------------- 25 | 26 | from ea.serverrepositories import RepoManager 27 | from ea.libs import Settings, Logger 28 | 29 | 30 | class RepoPublic(RepoManager.RepoManager, Logger.ClassLogger): 31 | def __init__(self): 32 | """ 33 | Repository manager for public test files 34 | """ 35 | RepoManager.RepoManager.__init__(self, pathRepo='%s%s' % (Settings.getDirExec(), 36 | Settings.get('Paths', 'public')), 37 | extensionsSupported=[]) 38 | 39 | 40 | RepoPublicMng = None 41 | 42 | 43 | def instance(): 44 | """ 45 | Returns the singleton 46 | """ 47 | return RepoPublicMng 48 | 49 | 50 | def initialize(): 51 | """ 52 | Instance creation 53 | """ 54 | global RepoPublicMng 55 | RepoPublicMng = RepoPublic() 56 | 57 | 58 | def finalize(): 59 | """ 60 | Destruction of the singleton 61 | """ 62 | global RepoPublicMng 63 | if RepoPublicMng: 64 | RepoPublicMng = None 65 | -------------------------------------------------------------------------------- /src/ea/serverrepositories/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ------------------------------------------------------------------- 5 | # Copyright (c) 2010-2021 Denis Machard 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | 14 | # The above copyright notice and this permission notice shall be included in all 15 | # copies or substantial portions of the Software. 16 | 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | # ------------------------------------------------------------------- 25 | -------------------------------------------------------------------------------- /src/ea/sutadapters/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ------------------------------------------------------------------ 5 | # Copyright (c) 2010-2021 Denis Machard 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | 14 | # The above copyright notice and this permission notice shall be included in all 15 | # copies or substantial portions of the Software. 16 | 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | # ------------------------------------------------------------------- 25 | 26 | __DESCRIPTION__ = "This library contains all adapters available to test your SUT (System Under Test)." 27 | 28 | __HELPER__ = [] 29 | 30 | __all__ = [] 31 | -------------------------------------------------------------------------------- /src/ea/test.ini: -------------------------------------------------------------------------------- 1 | [Network] 2 | keepalive-interval=40 3 | inactivity-timeout=120 4 | tcp-connect-timeout=5 5 | response-timeout=30 6 | 7 | [Trace] 8 | level=INFO 9 | 10 | [Csv_Tests_Results] 11 | ; Csv file header 12 | header=Type,TestName,Testcase,Step,Result 13 | ; separator between each values 14 | separator=, 15 | 16 | 17 | [Tests_Framework] 18 | ; stop the test if one is in error (not passed) 19 | ; 1 = yes 20 | ; 0 = no 21 | continue-on-step-error=1 22 | ; adding header on test report 23 | ; 1 = yes 24 | ; 0 = no 25 | header-test-report=1 26 | ; dispatch all events in the current testcase 27 | ; 1 = yes 28 | ; 0 = no 29 | dispatch-events-current-tc=0 30 | ; expand test in test report 31 | ; 1 = yes 32 | ; 0 = no 33 | expand-test-report=0 34 | ; display ignored testcases in test report 35 | ; 1 = yes 36 | ; 0 = no 37 | ignored-testcase-visible-test-report=0 38 | ; run test in background 39 | ; 1 = yes 40 | ; 0 = no 41 | test-in-background=0 42 | 43 | [Paths] 44 | tmp= 45 | templates= 46 | result= 47 | sut-adapters= 48 | public= 49 | 50 | [Event_Colors] 51 | ; colors values used on client to display events 52 | 53 | ; light blue and black colors 54 | state=#A0A0A0 55 | state-text=#FF5F5F 56 | 57 | ; black and red colors 58 | internal=#000000 59 | internal-text=#FF5F5F 60 | 61 | ; purple and write colors 62 | timer=#C2C2FF 63 | timer-text=#000000 64 | 65 | ; blue and black colors 66 | match=#93D9FF 67 | match-text=#000000 68 | 69 | ; light blue and black colors 70 | mismatch=#C9FFEB 71 | mismatch-text=#000000 72 | 73 | ; green and black colors 74 | payload=#8DFF7F 75 | payload-text=#000000 76 | 77 | ; grey and black colors 78 | info-tg=#E7E6FF 79 | info-tg-text=#000000 80 | 81 | ; grey and black colors 82 | info-tp=#E7E6FF 83 | info-tp-text=#000000 84 | 85 | ; grey and black colors 86 | info-ts=#E7E6FF 87 | info-ts-text=#000000 88 | 89 | ; yellow and black colors 90 | info-tc=#FFFA99 91 | info-tc-text=#000000 92 | 93 | ; dark yellow and black colors 94 | warning-tg=#FFFF00 95 | warning-tg-text=#000000 96 | 97 | ; dark yellow and black colors 98 | warning-tp=#FFFF00 99 | warning-tp-text=#000000 100 | 101 | ; dark yellow and black colors 102 | warning-ts=#FFFF00 103 | warning-ts-text=#000000 104 | 105 | ; dark orange and black colors 106 | warning-tc=#F0B501 107 | warning-tc-text=#000000 108 | 109 | ; red and black colors 110 | error-tg=#FF0000 111 | error-tg-text=#000000 112 | 113 | ; red and black colors 114 | error-tp=#FF0000 115 | error-tp-text=#000000 116 | 117 | ; red and black colors 118 | error-ts=#FF0000 119 | error-ts-text=#000000 120 | 121 | ; red and black colors 122 | error-tc=#FF0000 123 | error-tc-text=#000000 124 | 125 | ; dark green and black colors 126 | step-started=#CCCCCC 127 | step-started-text=#000000 128 | 129 | ; dark green and black colors 130 | step-passed=#2FC600 131 | step-passed-text=#000000 132 | 133 | ; red and black colors 134 | step-failed=#FF0000 135 | step-failed-text=#000000 -------------------------------------------------------------------------------- /src/ea/testcreatorlib/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ------------------------------------------------------------------- 5 | # Copyright (c) 2010-2021 Denis Machard 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | 14 | # The above copyright notice and this permission notice shall be included in all 15 | # copies or substantial portions of the Software. 16 | 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | # ------------------------------------------------------------------- 25 | -------------------------------------------------------------------------------- /src/ea/testexecutorlib/TestClientInterface.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ------------------------------------------------------------------- 5 | # Copyright (c) 2010-2021 Denis Machard 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | 14 | # The above copyright notice and this permission notice shall be included in all 15 | # copies or substantial portions of the Software. 16 | 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | # ------------------------------------------------------------------- 25 | 26 | 27 | from ea.testexecutorlib import TestSettings 28 | from ea.libs.NetLayerLib import ClientAgent as NetLayerLib 29 | import time 30 | import sys 31 | 32 | # unicode = str with python3 33 | if sys.version_info > (3,): 34 | unicode = str 35 | 36 | 37 | class TestClientInterface(NetLayerLib.ClientAgent): 38 | """ 39 | Test client interface 40 | """ 41 | 42 | def __init__(self, address, name): 43 | """ 44 | Constructor for the test client interface 45 | """ 46 | 47 | self.DEBUG_MODE = TestSettings.get('Trace', 'level') 48 | 49 | NetLayerLib.ClientAgent.__init__(self, 50 | typeAgent=NetLayerLib.TYPE_AGENT_USER, 51 | agentName='TEST', startAuto=True, forceClose=False, 52 | keepAliveInterval=TestSettings.getInt( 53 | 'Network', 'keepalive-interval'), 54 | inactivityTimeout=TestSettings.getInt( 55 | 'Network', 'inactivity-timeout'), 56 | timeoutTcpConnect=TestSettings.getInt( 57 | 'Network', 'tcp-connect-timeout'), 58 | responseTimeout=TestSettings.getInt( 59 | 'Network', 'response-timeout') 60 | ) 61 | _ip, _port = address 62 | self.setServerAddress(ip=_ip, port=_port) 63 | self.__test_name = name 64 | 65 | def onRequest(self, client, tid, request): 66 | """ 67 | On request 68 | """ 69 | pass 70 | 71 | def trace(self, txt): 72 | """ 73 | Display txt on screen 74 | """ 75 | if self.DEBUG_MODE == 'DEBUG': 76 | timestamp = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())) \ 77 | + ".%3.3d" % int((time.time() * 1000) % 1000) 78 | print( 79 | "%s | [%s] %s" % 80 | (timestamp, 81 | self.__class__.__name__, 82 | unicode(txt).encode('utf-8'))) 83 | 84 | 85 | TCI = None 86 | 87 | 88 | def instance(): 89 | """ 90 | Return instance 91 | """ 92 | return TCI 93 | 94 | 95 | def initialize(address, name): 96 | """ 97 | Initiliaze 98 | """ 99 | global TCI 100 | TCI = TestClientInterface(address=address, name=name) 101 | instance().startCA() 102 | 103 | 104 | def finalize(): 105 | """ 106 | Finalize 107 | """ 108 | instance().stopCA() 109 | global TCI 110 | if TCI: 111 | TCI = None 112 | -------------------------------------------------------------------------------- /src/ea/testexecutorlib/TestInteropLib.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ------------------------------------------------------------------- 5 | # Copyright (c) 2010-2021 Denis Machard 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | 14 | # The above copyright notice and this permission notice shall be included in all 15 | # copies or substantial portions of the Software. 16 | 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | # ------------------------------------------------------------------- 25 | 26 | from ea.testexecutorlib import TestLoggerXml as TLX 27 | from ea.testexecutorlib import TestTemplatesLib 28 | from ea.testexecutorlib import TestExecutorLib as TestExecutor 29 | 30 | 31 | class InteropException(Exception): 32 | pass 33 | 34 | 35 | FROM_LEVEL = "INTEROP" 36 | 37 | 38 | class InteropPlugin(object): 39 | def __init__(self, parent): 40 | """ 41 | """ 42 | self.tcparent = parent 43 | 44 | if not isinstance(parent, TestExecutor.TestCase): 45 | raise InteropException( 46 | "ERR_INT_001: testcase expected (%s)" % 47 | type(parent)) 48 | 49 | def logRequest(self, msg, details, raw=""): 50 | """ 51 | """ 52 | tpl = TestTemplatesLib.TemplateMessage() 53 | tpl.addLayer(details) 54 | tpl.addRaw(raw) 55 | try: 56 | TLX.instance().log_snd(msg, 57 | tpl.getEvent(), 58 | tpl.type(), 59 | TestExecutor.TC, self.tcparent.getId(), 60 | fromlevel=FROM_LEVEL, 61 | tolevel=self.__class__.__name__.upper(), 62 | testInfo=self.tcparent.getTestInfo()) 63 | except Exception as e: 64 | raise InteropException('ERR_INT_002: error on request: %s' % e) 65 | 66 | def logResponse(self, msg, details, raw=""): 67 | """ 68 | """ 69 | tpl = TestTemplatesLib.TemplateMessage() 70 | tpl.addLayer(details) 71 | tpl.addRaw(raw) 72 | try: 73 | TLX.instance().log_rcv(msg, 74 | tpl.getEvent(), 75 | tpl.type(), 76 | TestExecutor.TC, 77 | self.tcparent.getId(), 78 | fromlevel=self.__class__.__name__.upper(), 79 | tolevel=FROM_LEVEL, 80 | testInfo=self.tcparent.getTestInfo()) 81 | except Exception as e: 82 | raise InteropException('ERR_INT_003: error on response: %s' % e) 83 | 84 | def template(self, name, content): 85 | """ 86 | """ 87 | tplGenerator = TestTemplatesLib.Template() 88 | tpl = tplGenerator.prepareLayer(name=name, data=content) 89 | return tpl 90 | -------------------------------------------------------------------------------- /src/ea/testexecutorlib/TestReportingLib.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ------------------------------------------------------------------- 5 | # Copyright (c) 2010-2021 Denis Machard 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | 14 | # The above copyright notice and this permission notice shall be included in all 15 | # copies or substantial portions of the Software. 16 | 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | # ------------------------------------------------------------------- 25 | 26 | from ea.testexecutorlib import TestExecutorLib 27 | 28 | __DESCRIPTION__ = """The library enable to create test reporting in realtime.""" 29 | __HELPER__ = [ 30 | ('TestCases', ['__init__']) 31 | ] 32 | 33 | 34 | class TestCases(object): 35 | def __init__(self): 36 | """ 37 | Get all testcases as an iterator. 38 | Iterate on each testcase to get the verdict. 39 | """ 40 | self.i = -1 41 | 42 | def __str__(self): 43 | """ 44 | """ 45 | tcs = TestExecutorLib.getTsMgr().testcases() 46 | return "TestCases(nb=%s)" % len(tcs) 47 | 48 | def __iter__(self): 49 | """ 50 | """ 51 | return iter(TestExecutorLib.getTsMgr().testcases()) 52 | -------------------------------------------------------------------------------- /src/ea/testexecutorlib/TestSettings.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ------------------------------------------------------------------- 5 | # Copyright (c) 2010-2021 Denis Machard 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | 14 | # The above copyright notice and this permission notice shall be included in all 15 | # copies or substantial portions of the Software. 16 | 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | # ------------------------------------------------------------------- 25 | 26 | import os 27 | 28 | from ea.libs import Settings 29 | 30 | 31 | def getInt(section, key): 32 | """ 33 | Return value as integer according to the key 34 | """ 35 | return Settings.getInt(section, key) 36 | 37 | 38 | def get(section, key): 39 | """ 40 | Return value according to the key 41 | """ 42 | return Settings.get(section, key) 43 | 44 | 45 | def initialize(path="./"): 46 | """ 47 | Initialize settings 48 | """ 49 | Settings.initialize(path=os.path.normpath(path), cfgname='test.ini') 50 | 51 | 52 | def finalize(): 53 | """ 54 | Finalize settings 55 | """ 56 | Settings.finalize() 57 | -------------------------------------------------------------------------------- /src/ea/testexecutorlib/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ------------------------------------------------------------------- 5 | # Copyright (c) 2010-2021 Denis Machard 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | 14 | # The above copyright notice and this permission notice shall be included in all 15 | # copies or substantial portions of the Software. 16 | 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | # ------------------------------------------------------------------- 25 | 26 | __DESCRIPTION__ = """General library.""" 27 | -------------------------------------------------------------------------------- /src/ea/var/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ------------------------------------------------------------------- 5 | # Copyright (c) 2010-2020 Denis Machard 6 | # This file is part of the extensive automation project 7 | # 8 | # This library is free software; you can redistribute it and/or 9 | # modify it under the terms of the GNU Lesser General Public 10 | # License as published by the Free Software Foundation; either 11 | # version 2.1 of the License, or (at your option) any later version. 12 | # 13 | # This library is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | # Lesser General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU Lesser General Public 19 | # License along with this library; if not, write to the Free Software 20 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 21 | # MA 02110-1301 USA 22 | # ------------------------------------------------------------------- 23 | -------------------------------------------------------------------------------- /src/ea/var/data.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmachard/extensiveautomation-server/88038b67ae23a73baf88c71eaf52b01e9dc930f2/src/ea/var/data.db -------------------------------------------------------------------------------- /src/ea/var/templates/adapter_header.tpl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # ------------------------------------------------------------------ 5 | # Copyright (c) 2010-2021 Denis Machard 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | 14 | # The above copyright notice and this permission notice shall be included in all 15 | # copies or substantial portions of the Software. 16 | 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | # ------------------------------------------------------------------- -------------------------------------------------------------------------------- /src/ea/var/templates/design.tpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 17 |
Design #%s
User:%s
Project:%s
Testpath:%s
Testname:%s
Testcase:%s
Requirement:%s
Purpose:%s
Steps: 12 | 13 | 14 | %s 15 |
IDSummaryActionExpected
16 |
18 | -------------------------------------------------------------------------------- /src/ea/var/templates/png_failed.base64: -------------------------------------------------------------------------------- 1 | iVBORw0KGgoAAAANSUhEUgAAADkAAAARCAYAAABn5wTeAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuOWwzfk4AAAIsSURBVFhH3ZfbahNRFIa3iKAIVkQEUZHiA4heqvUQ2lCRekBBQaF3QswkRm/F4n1SqfT8DCX1tgcfwOYVbOhFpxbBCzvJnkySmfndazoT9owTsr3dCz4y+f91mJU5QBgA5v3eB//8Fn+eXtEC6/VN8C/vQXvRfsGC1uR1HDwZ1g7r1VV4v3bB7LKBg0eXtYX2Y838PVgPL2pL08iAWRMXoDvMenAeypSW4dGjLIX3dVzyvqEVq3mHbqSRv7cMHvNDPewlR3cm3Qv0ZI8BsMb9c1CmuASvVkr1nBrg1jbhrWYlvQQXm3DomGr3lsB7Xkg/PfJi86hfHZ2ilKMAa4yfhTKFRTG0mOIV4ZqL4PRJS8l69J1qg5zIC+mnR15iHl+tix9yNKYNgjWyZ6CMsZC4fTbgCJ1X63CnD3Pk40a2IJY8zAlqzQXwQJf4pyeFVLNViOdPb8CrZuLaAFhz7DSUyc+LoUZCN8QiiTDnYfc8ccJRbU+X6KdHXmKeXd2GW5FyFGDN0VNQ5s2cGJqPa5V1IKE5W+L5rNBxXiy5Dod0qjXnYEt5Af30yIv1lvr9B4xnTkKZ3Cz87zlJG0HX3EY3J+UQ5TVxNWfRyuTESa2hTRrVhhe6F9QrTRfhr4ykem45MUsBxu+egO6w1uQ18DvHtYX2Y+2Pz2HfPqYt7U8vwfz9HfFmG4J966h+iL188c4I/k/6P3fQ+fAMrRtHtMB5fAmdqRfwd3+I9cD+Am/2WWbdwFFuAAAAAElFTkSuQmCC -------------------------------------------------------------------------------- /src/ea/var/templates/png_passed.base64: -------------------------------------------------------------------------------- 1 | iVBORw0KGgoAAAANSUhEUgAAADkAAAARCAYAAABn5wTeAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuOWwzfk4AAAIvSURBVFhH3ZdNT1NBFIbnPxCjRqNGRWIMG0D84iu4gYYGNsqKBEkTXZkYUIzRaEjpj8Cw5WOhKIVqDLRQoYkssN3TNhYI7b6wfT0z91rOlLkDLrknedrpec/MOW8nN00FALF7UELo12vURjtR86nh1FMf68KzjbeQvqQ/ZbBu4SHOfG70HdejHSjs70I83XiDs3NNvkX6E21Lj3Fu7rZvaV/qhzj/pRl+R1ygFysrU8jJx5dHeQrdmr6OYb6H6N4quMVOLG+eQDP1olC6QeNn2hAXv96BlVU6nEwFWC5AQ+a2BtV6uEjNiuuVz+Y9g5goFzCx+r8aQ2rFMMuFsQx3H68zIC7N34WV5DQ1nkYPy/VkyWT2Ca3DiCuN3uk2R/geGuBj8nBPheO0ql6aVgprucM5WJ0BcXn+HqyooaqCBgmSFqQm8bRTx9cO42ScRWn8eM3UCym8/KdpZxDplDKp5QyIK9H7sJKcQb48g+ARLaIPKsNY5/CKfpfz2SG75tmLkFopouWcL5bVeCCuLjyAlZ9O497qfCZFNxDRcqM0bCLjalV7TqR59ZJITesXQYJueZTXeCCuLbbAytosNZ5Fn5YPYbK8jck1niOUAae2L7ftXq8T+VyoUuepyV5ujofSDVoiw3pbELWLrfA7IpAcwI1Yq2+R/sTzzXeoi7X5lhe/P0DsHOyh8UcXbn5r9x3S15/9Hbj/J/fI8Xu0xHtx63vHqadz5RFG0mPKIADxF9FwqJMJeBK/AAAAAElFTkSuQmCC -------------------------------------------------------------------------------- /src/ea/var/templates/png_undefined.base64: -------------------------------------------------------------------------------- 1 | iVBORw0KGgoAAAANSUhEUgAAADkAAAARCAYAAABn5wTeAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuOWwzfk4AAAH6SURBVFhH3ZfPShtRFIfvW5QiVApFWxWsgoi7gl10VUHc+ASiD1BTNfgkJg1uiohBpUqxrSbVhBRKNTEaMGTShoYkU0OC+T/Cr3fmjpO55grj7JwDX8ic7/xm7gnZDAGgkQrN4MT/Aj8/PnrwRLdeQgrP0bXYbtrH6WY/jtceO46Yv1dblPyJzCK23uVY1P1Icm8c8Y0njiX55TVIwt8Np0MuNp/CMoEVtHLvuF4+B1R/6Q77yN/p+NL66pzAqXVXrpV8a9zfKiS1/QyWCXrQyru4npynBzrWXUXiPOe4nAtVSCgFb3Ie/DWcCcHz7EDSn3pgmUMvlMJ7rvevANRO2i6bSrNrgTPn1DklNclcxYusyRkIcnYgmZ3nsMzRB/rQRa5XpIvUo2a3iDoCKApdO5eJBqBIU8zpf8V2sXyn0/v3hGR3+2CZkI8edonrlQppVEK3XCwA0O8lumQjJs7JUrrtqj7IJmcgyNmB5D4PwDpuNBBEWXQd9uFadhuzZZn99o3TTteRo0teGs5ER84eRN4bxL2If2en16sZ1/uRVXqgZdPsMpo3XnVs3Cgup/fMdf17WnBPe5Di1yE4HXIVmUL527BjUfcj9fg8rg5GHEv9bIG9itSOXqEWHHUedC91P+N9UjlfQDPyBs3DsQdP68cElIRbWxAA+Q8wzN5a0GsvzQAAAABJRU5ErkJggg== -------------------------------------------------------------------------------- /src/ea/var/templates/report.tpl: -------------------------------------------------------------------------------- 1 |

TestCase: %s

2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
Verdict:%s
Purpose:%s
Steps summaries:%s
Steps actions:%s
Steps expected:%s
Steps actual:%s
-------------------------------------------------------------------------------- /src/ea/var/tests/1/actions/basic/helloworld.yml: -------------------------------------------------------------------------------- 1 | properties: 2 | parameters: 3 | - name: msg 4 | value: hello world 5 | python: | 6 | class HelloWorld(Action): 7 | def definition(self): 8 | self.info(input("msg")) 9 | HelloWorld().execute() -------------------------------------------------------------------------------- /src/ea/var/tests/1/actions/basic/wait.yml: -------------------------------------------------------------------------------- 1 | properties: 2 | parameters: 3 | - name: duration 4 | value: 10 5 | python: | 6 | class Wait(Action): 7 | def definition(self): 8 | Timer(self).wait(timeout=input('duration')) 9 | Wait().execute() -------------------------------------------------------------------------------- /src/ea/var/tests/1/actions/cache/log.yml: -------------------------------------------------------------------------------- 1 | properties: 2 | parameters: 3 | - name: key 4 | value: 5 | python: | 6 | class CacheLog(Action): 7 | def definition(self): 8 | self.info("value=%s" % Cache().get(input("key"))) 9 | CacheLog().execute() -------------------------------------------------------------------------------- /src/ea/var/tests/1/actions/features/action_parameters.yml: -------------------------------------------------------------------------------- 1 | properties: 2 | parameters: 3 | - name: return-error 4 | value: false 5 | python: | 6 | class ACTION_PASS(Action): 7 | def definition(self): 8 | if input("return-error"): 9 | self.error("failure") 10 | else: 11 | self.info("success") 12 | ACTION_PASS().execute() -------------------------------------------------------------------------------- /src/ea/var/tests/1/actions/features/action_steps.yml: -------------------------------------------------------------------------------- 1 | python: | 2 | class TESTCASE_01(Action): 3 | def description(self): 4 | self.setPurpose(purpose=description('summary')) 5 | self.setRequirement(requirement=description('requirement')) 6 | 7 | # steps description 8 | self.step1 = self.addStep(expected="result expected", 9 | description="step description", 10 | summary="step sample", 11 | enabled=True) 12 | def prepare(self): 13 | pass 14 | 15 | def definition(self): 16 | # starting initial step 17 | if self.step1.isEnabled(): 18 | self.step1.start() 19 | 20 | self.info("message - info level") 21 | self.info("message - warning level") 22 | 23 | self.step1.setPassed(actual="success") 24 | 25 | def cleanup(self, aborted): 26 | pass 27 | 28 | TESTCASE_01(suffix=None).execute() -------------------------------------------------------------------------------- /src/ea/var/tests/1/actions/features/cache.yml: -------------------------------------------------------------------------------- 1 | properties: 2 | parameters: 3 | - name: REGEXP 4 | value: .*session_id=[!CAPTURE:SESSIONID:.*?:];.* 5 | - name: param-cache 6 | scope: cache 7 | value: hello world 8 | python: | 9 | class TESTCASE_CACHE(Action): 10 | def definition(self): 11 | data = [2, 3, {"de": 1}] 12 | key = "my key" 13 | Cache().set(name=key, data=data) 14 | 15 | cache = Cache().get(name=key) 16 | self.info( "data1 from cache: %s" % cache) 17 | 18 | cache = Cache().get(name="param-cache") 19 | self.info( "data2 from cache: %s" % cache) 20 | 21 | deleted = Cache().delete(name=key) 22 | if not deleted: 23 | self.error( "unable to delete data from cache" ) 24 | 25 | cache = Cache().get(name=key) 26 | self.info( "data from cache: %s" % cache) 27 | 28 | Cache().reset() 29 | 30 | class TESTCASE_CACHE_CAPTURE(Action): 31 | def definition(self): 32 | my_data="March, 25 2017 07:38:58 AM" 33 | Cache().capture(data=my_data, regexp=".* (?P