├── .github ├── actions │ ├── code-coverage │ │ └── action.yml │ └── setup-adaptived │ │ └── action.yml ├── dependabot.yml └── workflows │ ├── codeql-analysis.yml │ ├── continuous-integration.yml │ └── isolated.yml ├── .gitmodules ├── README.md ├── adaptived ├── .checkpatch.conf ├── .gitignore ├── CHANGELOG.txt ├── CONTRIBUTING.md ├── LICENSE.txt ├── Makefile.am ├── README.md ├── SECURITY.md ├── THIRD_PARTY_LICENSES.txt ├── autogen.sh ├── configure.ac ├── dist │ ├── .gitignore │ ├── Makefile.am │ └── adaptived.spec.in ├── doc │ ├── Makefile.am │ ├── examples │ │ ├── Makefile.am │ │ ├── adjust-weight.json │ │ ├── determine-memorylow.json │ │ ├── flow-chart.odp │ │ ├── flow-chart.png │ │ ├── jimmy-buffett-config.json │ │ ├── kill-lowpriority.json │ │ ├── lowmemfree-sendsignal.json │ │ └── topmem-savelogs.json │ └── internal │ │ ├── cgroup_setting_by_psi.md │ │ ├── human-readable.md │ │ ├── list-of-built-in-causes.md │ │ ├── list-of-built-in-effects.md │ │ └── path-rules.md ├── include │ ├── Makefile.am │ ├── adaptived-utils.h │ └── adaptived.h ├── m4 │ └── ax_code_coverage.m4 ├── sanity-check.sh ├── src │ ├── Makefile.am │ ├── adaptived-internal.h │ ├── cause.c │ ├── cause.h │ ├── causes │ │ ├── Makefile.am │ │ ├── always.c │ │ ├── cgroup_setting.c │ │ ├── days_of_the_week.c │ │ ├── meminfo.c │ │ ├── memorystat.c │ │ ├── periodic.c │ │ ├── pressure.c │ │ ├── pressure_rate.c │ │ ├── slabinfo.c │ │ ├── time_of_day.c │ │ └── top.c │ ├── defines.h │ ├── effect.c │ ├── effect.h │ ├── effects │ │ ├── cgroup_setting.c │ │ ├── cgroup_setting_by_psi.c │ │ ├── copy_cgroup_setting.c │ │ ├── kill_cgroup.c │ │ ├── kill_cgroup_by_psi.c │ │ ├── kill_processes.c │ │ ├── logger.c │ │ ├── print.c │ │ ├── print_schedstat.c │ │ ├── sd_bus_setting.c │ │ ├── snooze.c │ │ └── validate.c │ ├── log.c │ ├── main.c │ ├── parse.c │ ├── pressure.h │ ├── rule.c │ └── utils │ │ ├── Makefile.am │ │ ├── cgroup_utils.c │ │ ├── file_utils.c │ │ ├── float_utils.c │ │ ├── mem_utils.c │ │ ├── path_utils.c │ │ ├── pressure_utils.c │ │ ├── sched_utils.c │ │ └── sd_bus_utils.c └── tests │ ├── Makefile.am │ ├── ftests │ ├── .gitignore │ ├── 001-cause-time_of_day.json.token │ ├── 001-cause-time_of_day.py │ ├── 002-register_cause.c │ ├── 002-register_cause.json │ ├── 003-register_plugin_cause.c │ ├── 003-register_plugin_cause.json │ ├── 004-register_plugin_effect.c │ ├── 004-register_plugin_effect.json │ ├── 007-cause-avg300_pressure_above.c │ ├── 007-cause-avg300_pressure_above.json │ ├── 008-cause-pressure_above_total.c │ ├── 008-cause-pressure_above_total.json │ ├── 009-cause-pressure_below.c │ ├── 009-cause-pressure_below.json │ ├── 010-snooze_effect.c │ ├── 010-snooze_effect.json │ ├── 011-cause-pressure_rate_rising.c │ ├── 011-cause-pressure_rate_rising.json │ ├── 012-cause-pressure_rate_falling.c │ ├── 012-cause-pressure_rate_falling.json │ ├── 013-adaptived-asynchronous_loop.c │ ├── 013-adaptived-asynchronous_loop.json │ ├── 014-duplicate_cause_effect.c │ ├── 015-load_rule_at_runtime.c │ ├── 016-unload_rule_at_runtime.c │ ├── 017-register_many.c │ ├── 018-effect-cgroup_setting_set_str.c │ ├── 019-effect-cgroup_setting_set_int.c │ ├── 019-effect-cgroup_setting_set_int.json │ ├── 020-effect-cgroup_setting_add_int.c │ ├── 020-effect-cgroup_setting_add_int.json │ ├── 021-effect-cgroup_setting_sub_int.c │ ├── 021-effect-cgroup_setting_sub_int.json │ ├── 022-effect-kill_cgroup.c │ ├── 022-effect-kill_cgroup.json │ ├── 023-effect-kill_cgroup_recursive.c │ ├── 023-effect-kill_cgroup_recursive.json │ ├── 024-effect-kill_cgroup_by_psi.c │ ├── 024-effect-kill_cgroup_by_psi.json │ ├── 025-effect-cgroup_setting_by_psi_1.c │ ├── 025-effect-cgroup_setting_by_psi_1.json │ ├── 026-effect-cgroup_setting_by_psi_2.c │ ├── 026-effect-cgroup_setting_by_psi_2.json │ ├── 027-effect-cgroup_setting_by_psi_3.c │ ├── 027-effect-cgroup_setting_by_psi_3.json │ ├── 028-effect-copy_cgroup_setting.c │ ├── 028-effect-copy_cgroup_setting.json │ ├── 029-cause-cgroup_setting_ll_gt.c │ ├── 029-cause-cgroup_setting_ll_gt.json │ ├── 030-cause-cgroup_setting_ll_lt.c │ ├── 030-cause-cgroup_setting_ll_lt.json │ ├── 031-cause-cgroup_setting_float_gt.c │ ├── 031-cause-cgroup_setting_float_gt.json │ ├── 032-cause-cgroup_setting_float_lt.c │ ├── 032-cause-cgroup_setting_float_lt.json │ ├── 033-validate_humanize.c │ ├── 033-validate_humanize.json │ ├── 034-cause-setting_ll_gt.c │ ├── 034-cause-setting_ll_gt.json │ ├── 035-cause-setting_ll_lt.c │ ├── 035-cause-setting_ll_lt.json │ ├── 036-cause-setting_float_gt.c │ ├── 036-cause-setting_float_gt.json │ ├── 037-cause-setting_float_lt.c │ ├── 037-cause-setting_float_lt.json │ ├── 038-cause-setting_ll_eq.c │ ├── 038-cause-setting_ll_eq.json │ ├── 039-cause-setting_float_eq.c │ ├── 039-cause-setting_float_eq.json │ ├── 040-cause-avg300_pressure_equal.c │ ├── 040-cause-avg300_pressure_equal.json │ ├── 041-cause-pressure_equal.c │ ├── 041-cause-pressure_equal.json │ ├── 042-cause-periodic.c │ ├── 042-cause-periodic.json │ ├── 043-effect-logger-no-separators.c │ ├── 043-effect-logger-no-separators.json │ ├── 044-effect-logger-date-format.c │ ├── 044-effect-logger-date-format.json │ ├── 045-effect-cgroup_memory_setting_add_int_max.c │ ├── 045-effect-cgroup_memory_setting_add_int_max.json │ ├── 045-effect-cgroup_memory_setting_set_add_int.json │ ├── 046-effect-cgroup_memory_setting_sub_int_max.c │ ├── 046-effect-cgroup_memory_setting_sub_int_max.json │ ├── 047-effect-cgroup_memory_pre_set_add_int.c │ ├── 047-effect-cgroup_memory_pre_set_add_int.json │ ├── 048-cause-meminfo_gt.c │ ├── 048-cause-meminfo_gt.json │ ├── 049-cause-meminfo_lt.c │ ├── 049-cause-meminfo_lt.json │ ├── 050-cause-meminfo_eq.c │ ├── 050-cause-meminfo_eq.json │ ├── 051-cause-slabinfo_gt.c │ ├── 051-cause-slabinfo_gt.json │ ├── 052-cause-slabinfo_lt.c │ ├── 052-cause-slabinfo_lt.json │ ├── 053-cause-slabinfo_eq.c │ ├── 053-cause-slabinfo_eq.json │ ├── 054-effect-print_schedstat.expected │ ├── 054-effect-print_schedstat.json │ ├── 054-effect-print_schedstat.py │ ├── 054-effect-print_schedstat.schedstat │ ├── 055-effect-setting_set_int.c │ ├── 055-effect-setting_set_int.json │ ├── 056-effect-setting_add_int.c │ ├── 056-effect-setting_add_int.json │ ├── 057-effect-setting_sub_int.c │ ├── 057-effect-setting_sub_int.json │ ├── 058-cause-memorystat_gt.c │ ├── 058-cause-memorystat_gt.expected │ ├── 058-cause-memorystat_gt.json │ ├── 058-cause-memorystat_gt.token │ ├── 059-cause-memorystat_lt.c │ ├── 059-cause-memorystat_lt.expected │ ├── 059-cause-memorystat_lt.json │ ├── 059-cause-memorystat_lt.token │ ├── 060-cause-memorystat_eq.c │ ├── 060-cause-memorystat_eq.expected │ ├── 060-cause-memorystat_eq.json │ ├── 060-cause-memorystat_eq.token │ ├── 061-cause-top_cpu_gt.c │ ├── 061-cause-top_cpu_gt.json │ ├── 061-proc_stat.sample │ ├── 062-cause-top_cpu_lt.c │ ├── 062-cause-top_cpu_lt.json │ ├── 063-cause-top_mem_gt.c │ ├── 063-cause-top_mem_gt.json │ ├── 064-cause-top_mem_lt.c │ ├── 064-cause-top_mem_lt.json │ ├── 065-daemon_test.c │ ├── 066-cause-cgroup_memory_setting_ll_lt.c │ ├── 066-cause-cgroup_memory_setting_ll_lt.json │ ├── 067-effect-kill_processes.c │ ├── 067-effect-kill_processes.json │ ├── 068-effect-kill_processes_rss.c │ ├── 068-effect-kill_processes_rss.json │ ├── 069-effect-signal.c │ ├── 069-effect-signal.json │ ├── 070-rule-multiple_rules.c │ ├── 070-rule-multiple_rules.json │ ├── 1000-sudo-effect-sd_bus_setting_set_int.c │ ├── 1000-sudo-effect-sd_bus_setting_set_int.json │ ├── 1001-sudo-effect-sd_bus_setting_add_int.c │ ├── 1001-sudo-effect-sd_bus_setting_add_int.json │ ├── 1002-sudo-effect-sd_bus_setting_sub_int.c │ ├── 1002-sudo-effect-sd_bus_setting_sub_int.json │ ├── 1003-sudo-effect-sd_bus_setting-CPUQuota.c │ ├── 1003-sudo-effect-sd_bus_setting-CPUQuota.json │ ├── 1004-sudo-effect-sd_bus_setting_add_int_infinity.c │ ├── 1004-sudo-effect-sd_bus_setting_add_int_infinity.json │ ├── 1005-sudo-effect-sd_bus_setting_sub_infinity.c │ ├── 1005-sudo-effect-sd_bus_setting_sub_infinity.json │ ├── 1006-sudo-effect-sd_bus_setting_set_int_scope.c │ ├── 1006-sudo-effect-sd_bus_setting_set_int_scope.json │ ├── 1007-sudo-effect-sd_bus_setting_set_str.c │ ├── 1007-sudo-effect-sd_bus_setting_set_str.json │ ├── Makefile.am │ ├── adaptived.py │ ├── config.py │ ├── consts.py │ ├── ftests-c-wrapper.sh │ ├── ftests-wrapper.sh │ ├── ftests.c │ ├── ftests.h │ ├── ftests.py │ ├── log.py │ ├── run.py │ ├── time_of_day.c │ ├── tod_validate.c │ └── utils.py │ └── gunit │ ├── 001-adaptived_get_pressure.cpp │ ├── 002-adaptived_get_pressure_avg.cpp │ ├── 003-adaptived_farray_append.cpp │ ├── 004-adaptived_farray_linear_regression.cpp │ ├── 005-cgroup_long_long.cpp │ ├── 006-cgroup_str.cpp │ ├── 007-path_walk.cpp │ ├── 008-cgroup_get_procs.cpp │ ├── 009-cgroup_detect.cpp │ ├── 010-adaptived_get_schedstats.cpp │ ├── 011-kill_processes_sort.cpp │ ├── Makefile.am │ └── gtest.cpp ├── adaptivemm ├── 50-adaptivemm.preset ├── CONTRIBUTING.md ├── LICENSE.txt ├── README.md ├── SECURITY.md ├── adaptivemm.spec ├── adaptivemmd.cfg ├── adaptivemmd.service ├── doc │ └── adaptivemmd.8 └── src │ ├── Makefile │ ├── adaptivemmd.c │ ├── predict.c │ └── predict.h └── tools ├── build_spec.yaml └── diff.sh /.github/actions/code-coverage/action.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Action to collate the adaptived code coverage data 3 | # 4 | # Copyright (c) 2021-2024 Oracle and/or its affiliates. 5 | # Author: Tom Hromatka 6 | # 7 | 8 | name: Collate code coverage results 9 | description: "Collate code coverage results" 10 | runs: 11 | using: "composite" 12 | steps: 13 | - run: lcov -d . -c -o lcov.tests 14 | shell: bash 15 | - run: lcov -a lcov.base -a lcov.tests -o lcov.total 16 | shell: bash 17 | -------------------------------------------------------------------------------- /.github/actions/setup-adaptived/action.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Action to setup the adaptived directory 3 | # 4 | # Note: based on libcgroup's setup-libcgroup/action.yml 5 | # 6 | # Copyright (c) 2020-2024 Oracle and/or its affiliates. 7 | # Author: Tom Hromatka 8 | # 9 | 10 | name: Setup the adaptived directory 11 | description: "Install dependencies, git clone, bootstrap, configure, and make adaptived" 12 | runs: 13 | using: "composite" 14 | steps: 15 | - run: | 16 | while sudo fuser /var/{lib/{dpkg,apt/lists},cache/apt/archives}/lock >/dev/null 2>&1; do sleep 3; done 17 | sudo apt-get update 18 | shell: bash 19 | - run: | 20 | while sudo fuser /var/{lib/{dpkg,apt/lists},cache/apt/archives}/lock >/dev/null 2>&1; do sleep 3; done 21 | sudo apt-get install libjson-c-dev lcov cmake bison flex autoconf automake libtool libsystemd-dev -y 22 | shell: bash 23 | - run: cd adaptived && ./autogen.sh 24 | shell: bash 25 | - run: cd adaptived && CFLAGS="$CFLAGS -g -O0 -Werror" ./configure --enable-code-coverage 26 | shell: bash 27 | - run: cd adaptived && make 28 | shell: bash 29 | - run: lcov -i -d . -c -o lcov.base 30 | shell: bash 31 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Dependabot Workflow for adaptived 3 | # 4 | # Copyright (c) 2023-2024 Oracle and/or its affiliates. 5 | # Author: Tom Hromatka 6 | # 7 | 8 | # based on this guide from GitHub: 9 | # https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot 10 | 11 | version: 2 12 | updates: 13 | 14 | - package-ecosystem: "github-actions" 15 | directory: "/adaptived" 16 | schedule: 17 | # Check for updates to GitHub Actions every week 18 | interval: "weekly" 19 | commit-message: 20 | prefix: "RFE: " 21 | labels: 22 | - "enhancement" 23 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024, Oracle and/or its affiliates. 2 | # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 | # 4 | # This code is free software; you can redistribute it and/or modify it 5 | # under the terms of the GNU General Public License version 2 only, as 6 | # published by the Free Software Foundation. 7 | # 8 | # This code is distributed in the hope that it will be useful, but WITHOUT 9 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11 | # version 2 for more details (a copy is included in the LICENSE file that 12 | # accompanied this code). 13 | # 14 | # You should have received a copy of the GNU General Public License version 15 | # 2 along with this work; if not, write to the Free Software Foundation, 16 | # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 17 | # 18 | # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 19 | # or visit www.oracle.com if you need additional information or have any 20 | # questions. 21 | # 22 | # Continuous Integration Workflow for adaptived 23 | # 24 | # Note: based on libcgroup's codeql-analysis.yml 25 | # 26 | 27 | name: "CodeQL" 28 | on: ["push", "pull_request"] 29 | 30 | jobs: 31 | codeql: 32 | name: CodeQL 33 | runs-on: ubuntu-latest 34 | 35 | steps: 36 | - uses: actions/checkout@v3 37 | with: 38 | submodules: false 39 | - uses: github/codeql-action/init@v2 40 | with: 41 | languages: cpp, python 42 | - name: Initialize the directory 43 | uses: ./.github/actions/setup-adaptived 44 | - name: Perform CodeQL Analysis 45 | uses: github/codeql-action/analyze@v2 46 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "adaptived/googletest"] 2 | path = adaptived/googletest 3 | url = https://github.com/google/googletest.git 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Adaptive Tools 2 | ## Overview 3 | This repo contains the source for the adaptivemm and adaptived tools. 4 | 5 | [adaptivemm](./adaptivemm/README.md) monitors a machine's memory usage to track the rate of page consumption. It then uses this information to predict future memory usage and adjusts the watermark scale factor sysctl to kick off proactive background memory reclamation. This is done to avoid costly synchronous memory reclaim which can stall applications. 6 | 7 | [adaptived](./adaptived/README.md) is a cause-and-effect daemon in which a user can specify their own causes which are used to decide if a certain action should be done in reponse to this cause. 8 |
9 | 10 | Further information for both tools is found in their respective directories. 11 | -------------------------------------------------------------------------------- /adaptived/.checkpatch.conf: -------------------------------------------------------------------------------- 1 | # There is no Kernel tree available, run without it. 2 | --no-tree 3 | 4 | # Ignore the SPDX License tag, that's supposed to be the first line in 5 | # Linux Kernel sources. 6 | --ignore SPDX_LICENSE_TAG 7 | 8 | # Follow the 100-character limit. 9 | --max-line-length=100 10 | 11 | # Kernel specific kstr* functions recommendation doesn't apply to us. 12 | --ignore SSCANF_TO_KSTRTO 13 | 14 | # Ignore Kernel str* function recommendations 15 | --ignore STRCPY 16 | --ignore STRNCPY 17 | 18 | # Ignore the suggestion to add file changes (add, move, or delete) to the 19 | # MAINTAINERS file 20 | --ignore FILE_PATH_CHANGES 21 | -------------------------------------------------------------------------------- /adaptived/.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.css 3 | *.la 4 | *.lo 5 | *.o 6 | *.pc 7 | *.swp 8 | *.orig 9 | *.gcno 10 | *.gcda 11 | *.html 12 | *.info 13 | *.log 14 | *.trs 15 | *-coverage/ 16 | .deps 17 | .dirstamp 18 | .libs 19 | configure 20 | Makefile 21 | Makefile.in 22 | cscope.* 23 | tags 24 | gtest 25 | /autom4te.cache 26 | /aclocal.m4 27 | /build-aux 28 | /config.* 29 | /configure 30 | /configure.h* 31 | /libtool 32 | /m4 33 | /stamp-h1 34 | /cov-int 35 | /src/adaptived 36 | -------------------------------------------------------------------------------- /adaptived/CHANGELOG.txt: -------------------------------------------------------------------------------- 1 | adaptived: Releases 2 | =============================================================================== 3 | https://github.com/oracle/adaptivemm 4 | 5 | * Version 1.0.1 - February 24, 2025 6 | - Fix bug where only two or fewer rules could be loaded 7 | - Fix duration bug in PSI cause 8 | - Fix memory leak reported by coverity 9 | 10 | * Version 1.0.0 - November 8, 2024 11 | - Initial release 12 | -------------------------------------------------------------------------------- /adaptived/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to the adaptived repository 2 | 3 | We welcome your contributions! There are multiple ways to contribute. 4 | 5 | ## Opening issues 6 | 7 | For bugs or enhancement requests, please file a GitHub issue unless it's 8 | security related. When filing a bug remember that the better written the bug is, 9 | the more likely it is to be fixed. If you think you've found a security 10 | vulnerability, do not raise a GitHub issue and follow the instructions in our 11 | [security policy](./SECURITY.md). 12 | 13 | ## Contributing code 14 | 15 | We welcome your code contributions. Before submitting code via a pull request, 16 | you will need to have signed the [Oracle Contributor Agreement][OCA] (OCA) and 17 | your commits need to include the following line using the name and e-mail 18 | address you used to sign the OCA: 19 | 20 | ```text 21 | Signed-off-by: Your Name 22 | ``` 23 | 24 | This can be automatically added to pull requests by committing with `--sign-off` 25 | or `-s`, e.g. 26 | 27 | ```text 28 | git commit --signoff 29 | ``` 30 | 31 | Only pull requests from committers that can be verified as having signed the OCA 32 | can be accepted. 33 | 34 | ## Pull request process 35 | 36 | 1. Fork this repository. 37 | 1. Create a branch in your fork to implement the changes. We recommend using 38 | the issue number as part of your branch name, e.g. `1234-fixes`. 39 | 1. Ensure that any documentation is updated with the changes that are required 40 | by your change. 41 | 1. Ensure that any samples are updated if the base image has been changed. 42 | 1. Submit the pull request. *Do not leave the pull request blank*. Explain exactly 43 | what your changes are meant to do and provide simple steps on how to validate. 44 | your changes. Ensure that you reference the issue you created as well. 45 | 1. We will assign the pull request to 2-3 people for review before it is merged. 46 | 47 | ## Code of conduct 48 | 49 | Follow the [Golden Rule](https://en.wikipedia.org/wiki/Golden_Rule). If you'd 50 | like more specific guidelines, see the [Contributor Covenant Code of Conduct][COC]. 51 | 52 | [OCA]: https://oca.opensource.oracle.com 53 | [COC]: https://www.contributor-covenant.org/version/1/4/code-of-conduct/ 54 | -------------------------------------------------------------------------------- /adaptived/Makefile.am: -------------------------------------------------------------------------------- 1 | ACLOCAL_AMFLAGS = -I m4 2 | DIST_SUBDIRS = dist doc include src tests 3 | SUBDIRS = ${DIST_SUBDIRS} 4 | 5 | EXTRA_DIST = \ 6 | CHANGELOG.txt \ 7 | CONTRIBUTING.md \ 8 | LICENSE.txt \ 9 | README.md \ 10 | SECURITY.md \ 11 | THIRD_PARTY_LICENSES.txt 12 | 13 | help: 14 | @echo "adaptived build system" 15 | @echo " make targets:" 16 | @echo " (none): build the library" 17 | @echo " check: build the library and run tests" 18 | @echo " check-build: build the library and all tests" 19 | 20 | check-build: all 21 | ${MAKE} ${AM_MAKEFLAGS} -C src check-build 22 | ${MAKE} ${AM_MAKEFLAGS} -C tests check-build 23 | -------------------------------------------------------------------------------- /adaptived/SECURITY.md: -------------------------------------------------------------------------------- 1 | # Reporting security vulnerabilities 2 | 3 | Oracle values the independent security research community and believes that 4 | responsible disclosure of security vulnerabilities helps us ensure the security 5 | and privacy of all our users. 6 | 7 | Please do NOT raise a GitHub Issue to report a security vulnerability. If you 8 | believe you have found a security vulnerability, please submit a report to 9 | [secalert_us@oracle.com][1] preferably with a proof of concept. Please review 10 | some additional information on [how to report security vulnerabilities to Oracle][2]. 11 | We encourage people who contact Oracle Security to use email encryption using 12 | [our encryption key][3]. 13 | 14 | We ask that you do not use other channels or contact the project maintainers 15 | directly. 16 | 17 | Non-vulnerability related security issues including ideas for new or improved 18 | security features are welcome on GitHub Issues. 19 | 20 | ## Security updates, alerts and bulletins 21 | 22 | Security updates will be released on a regular cadence. Many of our projects 23 | will typically release security fixes in conjunction with the 24 | Oracle Critical Patch Update program. Additional 25 | information, including past advisories, is available on our [security alerts][4] 26 | page. 27 | 28 | ## Security-related information 29 | 30 | We will provide security related information such as a threat model, considerations 31 | for secure use, or any known security issues in our documentation. Please note 32 | that labs and sample code are intended to demonstrate a concept and may not be 33 | sufficiently hardened for production use. 34 | 35 | [1]: mailto:secalert_us@oracle.com 36 | [2]: https://www.oracle.com/corporate/security-practices/assurance/vulnerability/reporting.html 37 | [3]: https://www.oracle.com/security-alerts/encryptionkey.html 38 | [4]: https://www.oracle.com/security-alerts/ 39 | -------------------------------------------------------------------------------- /adaptived/autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | 4 | git submodule update --init --recursive 5 | 6 | # configure googletest 7 | pushd googletest/googletest 8 | git checkout release-1.8.0 9 | cmake -DBUILD_SHARED_LIBS=ON . 10 | make 11 | popd 12 | 13 | test -d m4 || mkdir m4 14 | autoreconf -fi 15 | rm -rf autom4te.cache 16 | -------------------------------------------------------------------------------- /adaptived/configure.ac: -------------------------------------------------------------------------------- 1 | dnl # Copyright (c) 2024, Oracle and/or its affiliates. 2 | dnl # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 | dnl # 4 | dnl # This code is free software; you can redistribute it and/or modify it 5 | dnl # under the terms of the GNU General Public License version 2 only, as 6 | dnl # published by the Free Software Foundation. 7 | dnl # 8 | dnl # This code is distributed in the hope that it will be useful, but WITHOUT 9 | dnl # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 | dnl # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11 | dnl # version 2 for more details (a copy is included in the LICENSE file that 12 | dnl # accompanied this code). 13 | dnl # 14 | dnl # You should have received a copy of the GNU General Public License version 15 | dnl # 2 along with this work; if not, write to the Free Software Foundation, 16 | dnl # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 17 | dnl # 18 | dnl # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 19 | dnl # or visit www.oracle.com if you need additional information or have any 20 | dnl # questions. 21 | 22 | AC_INIT([adaptived],[0.0.0]) 23 | 24 | dnl # 25 | dnl # autoconf configuration 26 | dnl # 27 | AC_CONFIG_AUX_DIR([build-aux]) 28 | AC_CONFIG_HEADERS([configure.h]) 29 | AC_CONFIG_MACRO_DIR([m4]) 30 | AM_INIT_AUTOMAKE(-Wall foreign subdir-objects) 31 | 32 | m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) 33 | m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) 34 | 35 | dnl # 36 | dnl # build flags 37 | dnl # 38 | AM_CPPFLAGS="-I\${top_srcdir}/include -I\${top_builddir}/include" 39 | AM_CFLAGS="-Wall" 40 | AM_LDFLAGS="-Wl,-z -Wl,relro" 41 | AC_SUBST([AM_CPPFLAGS]) 42 | AC_SUBST([AM_CFLAGS]) 43 | AC_SUBST([AM_LDFLAGS]) 44 | 45 | dnl # 46 | dnl # version information 47 | dnl # 48 | VERSION_MAJOR=$(echo ${VERSION} | cut -d'.' -f 1) 49 | VERSION_MINOR=$(echo ${VERSION} | cut -d'.' -f 2) 50 | VERSION_MICRO=$(echo ${VERSION} | cut -d'.' -f 3) 51 | AC_SUBST([VERSION_MAJOR]) 52 | AC_SUBST([VERSION_MINOR]) 53 | AC_SUBST([VERSION_MICRO]) 54 | 55 | dnl # 56 | dnl # Determine which C compiler to use 57 | dnl # 58 | AC_PROG_CXX 59 | AC_PROG_CC 60 | AM_PROG_CC_C_O 61 | 62 | dnl # 63 | dnl # Dependencies 64 | dnl # 65 | AC_CHECK_LIB([json-c], [json_object_object_get_ex], [], 66 | [AC_MSG_ERROR([please install json-c])]) 67 | 68 | AC_CHECK_HEADERS([json-c/json.h], [], 69 | [AC_MSG_ERROR([please install the json-c development package])]) 70 | 71 | LT_INIT 72 | 73 | dnl # 74 | dnl # Enable/Disable code coverage 75 | dnl # 76 | AX_CODE_COVERAGE 77 | 78 | dnl # 79 | dnl # makefiles 80 | dnl # 81 | AC_CONFIG_FILES([ 82 | Makefile 83 | dist/Makefile 84 | doc/Makefile 85 | doc/examples/Makefile 86 | include/Makefile 87 | src/Makefile 88 | tests/Makefile 89 | tests/ftests/Makefile 90 | tests/gunit/Makefile 91 | ]) 92 | AC_CONFIG_FILES([dist/adaptived.spec:dist/adaptived.spec.in]) 93 | 94 | dnl # 95 | dnl # generate the configure and makefiles 96 | dnl # 97 | AC_OUTPUT 98 | -------------------------------------------------------------------------------- /adaptived/dist/.gitignore: -------------------------------------------------------------------------------- 1 | adaptived.spec 2 | -------------------------------------------------------------------------------- /adaptived/dist/Makefile.am: -------------------------------------------------------------------------------- 1 | EXTRA_DIST = adaptived.spec 2 | -------------------------------------------------------------------------------- /adaptived/dist/adaptived.spec.in: -------------------------------------------------------------------------------- 1 | Name: adaptived 2 | Version: @PACKAGE_VERSION@ 3 | Release: 1%{?dist} 4 | Summary: Adaptived cause-and-effect daemon 5 | License: GPLv2 6 | URL: https://linux-git.oraclecorp.com/thromatk/adaptived 7 | Source0: %{url}/releases/download/v%{version}/%{name}-%{version}.tar.gz 8 | 9 | # Backports from upstream 10 | 11 | BuildRequires: json-c, json-c-devel, systemd, systemd-devel 12 | BuildRequires: gcc 13 | BuildRequires: gperf 14 | BuildRequires: make 15 | Requires: json-c, systemd 16 | 17 | BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root 18 | 19 | %description 20 | Adaptived is a simple cause-and-effect daemon for the Linux operating system. It 21 | is designed to allow a user to construct a series of rules to automate tasks. 22 | 23 | # 24 | # The devel package is intentionally disabled at present 25 | # 26 | # package devel 27 | # Summary: Development files used to build applications that directly interact with the adaptived C APIs 28 | # Requires: %{name}%{?_isa} = %{version}-%{release} 29 | # 30 | # %description devel 31 | # Adaptived is a simple cause-and-effect daemon for the Linux operating system. It 32 | # is designed to allow a user to construct a series of rules to automate tasks. 33 | # The adaptived C API allows for the creation of custom causes and effects. 34 | # Rules can also be added and deleted at runtime. Finally, adaptived settings, 35 | # e.g. logging level, can be changed at runtime. 36 | 37 | %prep 38 | %autosetup -p1 39 | 40 | %build 41 | %configure 42 | %make_build 43 | 44 | %install 45 | mkdir -p %{buildroot}/%{_sbindir} 46 | mkdir -p %{buildroot}/%{_libdir} 47 | mkdir -p %{buildroot}/%{_includedir} 48 | mkdir -p %{buildroot}/%{_mandir} 49 | 50 | %make_install 51 | 52 | rm -f %{buildroot}/%{_libdir}/libadaptived.a 53 | 54 | # Since the devel RPM is disabled, delete its files 55 | rm -f %{buildroot}/%{_includedir}/adaptived.h 56 | rm -f %{buildroot}/%{_includedir}/adaptived-utils.h 57 | rm -f %{buildroot}/%{_libdir}/libadaptived.so* 58 | rm -f %{buildroot}/%{_libdir}/libadaptived.la* 59 | 60 | %check 61 | 62 | %make_build check 63 | 64 | %files 65 | %license LICENSE.txt THIRD_PARTY_LICENSES.txt 66 | %doc CONTRIBUTING.md README.md SECURITY.md 67 | %{_sbindir}/adaptived 68 | 69 | # %files devel 70 | # %{_includedir}/adaptived.h 71 | # %{_includedir}/adaptived-utils.h 72 | # %{_libdir}/libadaptived.so* 73 | # %{_libdir}/libadaptived.la* 74 | 75 | %changelog 76 | * Fri Oct 18 2024 Tom Hromatka 77 | - Disable devel package 78 | * Wed Oct 16 2024 Tom Hromatka , George Kennedy 0.0.0 79 | - Initial version 80 | -------------------------------------------------------------------------------- /adaptived/doc/Makefile.am: -------------------------------------------------------------------------------- 1 | DIST_SUBDIRS = examples 2 | -------------------------------------------------------------------------------- /adaptived/doc/examples/Makefile.am: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/adaptivemm/bf6bb6c0673f6f9a948e43a665cc24c1f0b52355/adaptived/doc/examples/Makefile.am -------------------------------------------------------------------------------- /adaptived/doc/examples/determine-memorylow.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "When there is memory pressure, increase the cgroup's memory.high", 5 | "description": "These rules can be used to determine an application's minimum memory required. In other words, these two rules will adjust memory.high to exert memory pressure on the application, and ultimately memory.high will settle approximately at the level where memory pressure is starting to be felt by the application. The memory.high value computed by this config file can then be used to populate the cgroup's memory.low to ensure that the application gets the minimum memory needed before it experiences memory pressure.", 6 | "causes": [ 7 | { 8 | "name": "pressure", 9 | "args": { 10 | "pressure_file": "/sys/fs/cgroup/database.slice/db1.scope/memory.pressure", 11 | "threshold": 8.0, 12 | "duration": 20000, 13 | "operator": "greaterthan", 14 | "measurement": "some-avg60" 15 | } 16 | } 17 | ], 18 | "effects": [ 19 | { 20 | "name": "cgroup_memory_setting", 21 | "args": { 22 | "setting": "/sys/fs/cgroup/database.slice/db1.scope/memory.high", 23 | "value": "100M", 24 | "operator": "add" 25 | } 26 | } 27 | ] 28 | }, 29 | { 30 | "name": "When memory pressure has abated, decrease the cgroup's memory.high", 31 | "causes": [ 32 | { 33 | "name": "pressure", 34 | "args": { 35 | "pressure_file": "/sys/fs/cgroup/database.slice/db1.scope/memory.pressure", 36 | "threshold": 2.0, 37 | "duration": 20000, 38 | "operator": "lessthan", 39 | "measurement": "some-avg60" 40 | } 41 | } 42 | ], 43 | "effects": [ 44 | { 45 | "name": "cgroup_memory_setting", 46 | "args": { 47 | "setting": "/sys/fs/cgroup/database.slice/db1.scope/memory.high", 48 | "value": "100M", 49 | "operator": "subtract", 50 | "limit": "100M" 51 | } 52 | } 53 | ] 54 | } 55 | ] 56 | } 57 | -------------------------------------------------------------------------------- /adaptived/doc/examples/flow-chart.odp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/adaptivemm/bf6bb6c0673f6f9a948e43a665cc24c1f0b52355/adaptived/doc/examples/flow-chart.odp -------------------------------------------------------------------------------- /adaptived/doc/examples/flow-chart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle/adaptivemm/bf6bb6c0673f6f9a948e43a665cc24c1f0b52355/adaptived/doc/examples/flow-chart.png -------------------------------------------------------------------------------- /adaptived/doc/examples/jimmy-buffett-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Tell me when it's after 5pm on a weekday", 5 | "description": "Jimmy Buffett rule. It may be 5 o'clock somewhere, but is it 5 o'clock here? :)", 6 | "causes": [ 7 | { 8 | "name": "time_of_day", 9 | "args": { 10 | "time": "17:00:00", 11 | "operator": "greaterthan" 12 | } 13 | }, 14 | { 15 | "name": "days_of_the_week", 16 | "args": { 17 | "days": [ 18 | { 19 | "day": "monday" 20 | }, 21 | { 22 | "day": "tuesday" 23 | }, 24 | { 25 | "day": "wednesday" 26 | }, 27 | { 28 | "day": "thursday" 29 | }, 30 | { 31 | "day": "friday" 32 | } 33 | ] 34 | } 35 | } 36 | ], 37 | "effects": [ 38 | { 39 | "name": "print", 40 | "args": { 41 | "message": "It's 5 o'clock here :)\n", 42 | "file": "stderr" 43 | } 44 | } 45 | ] 46 | } 47 | ] 48 | } 49 | -------------------------------------------------------------------------------- /adaptived/doc/examples/kill-lowpriority.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "When there is pressure on the high-priority cgroup, kill processes in the low-priority cgroup", 5 | "description": "This configuration was motivated by Meta's oomd daemon. By placing important processes in a cgroup, say highpriority.scope, adaptived can ensure that these processes get utmost priority when there is additional load on the machine. In this example, adaptived kills processes in the low-priority cgroup until the pressure abates. Note that unlike oomd, adaptived can operated on memory, cpu, or io PSI pressure (or some other measurement entirely) and not just memory", 6 | "causes": [ 7 | { 8 | "name": "pressure", 9 | "args": { 10 | "pressure_file": "/sys/fs/cgroup/database.slice/highpriority.scope/cpu.pressure", 11 | "threshold": 10.0, 12 | "operator": "greaterthan", 13 | "measurement": "full-avg10", 14 | "duration": 2000 15 | } 16 | } 17 | ], 18 | "effects": [ 19 | { 20 | "name": "kill_cgroup", 21 | "args": { 22 | "cgroup": "/sys/fs/cgroup/database.slice/lowpriority.scope", 23 | "count": 1 24 | } 25 | } 26 | ] 27 | } 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /adaptived/doc/examples/lowmemfree-sendsignal.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "When MemFree falls below 2 GB, send SIGALRM (signal 14) to the monitoring program", 5 | "description": "This configuration file will monitor MemFree in /proc/meminfo, and when it falls below 2 GB, it will send a signal to the monitoring program. The monitoring program could then disable low-priority processes, migrate some processes to another machine, or if this is a VM, add more memory to the VM.", 6 | "causes": [ 7 | { 8 | "name": "meminfo", 9 | "args": { 10 | "field": "MemFree", 11 | "threshold": "2G", 12 | "operator": "lessthan" 13 | } 14 | } 15 | ], 16 | "effects": [ 17 | { 18 | "name": "signal", 19 | "args": { 20 | "proc_names": [ 21 | { "name": "monitor_program" } 22 | ], 23 | "signal": 14 24 | } 25 | } 26 | ] 27 | } 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /adaptived/doc/examples/topmem-savelogs.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "When mem used (according to top) exceeds 4G, save off critical memory logs", 5 | "description": "When memory exceeds a certain threshold, this could be a sign of a memory leak or other problem. Save off critical log files for later analysis. This could be useful on production machines where more intrusive debugging mechanisms aren't available.", 6 | "causes": [ 7 | { 8 | "name": "top", 9 | "args": { 10 | "component": "mem", 11 | "field": "used", 12 | "threshold": "4G", 13 | "operator": "greaterthan" 14 | } 15 | } 16 | ], 17 | "effects": [ 18 | { 19 | "name": "logger", 20 | "args": { 21 | "logfile": "anomaly.log", 22 | "date_format": "%Y-%m-%d-%H:%M:%S-%Z", 23 | "utc": true, 24 | "files": [ 25 | { 26 | "file": "/proc/meminfo" 27 | }, 28 | { 29 | "file": "/proc/slabinfo" 30 | } 31 | ] 32 | } 33 | } 34 | ] 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /adaptived/doc/internal/human-readable.md: -------------------------------------------------------------------------------- 1 | ## Supported Human-Readable Formats 2 | 3 | * Float, e.g. 123.45 4 | * Integer, e.g. 12345 5 | * Kilobytes, e.g. 123K 6 | * Megabytes, e.g. 123M 7 | * Gigabytes, e.g. 123G 8 | * Terabytes, e.g. 123T 9 | 10 | ** NOTE - lowercase suffixes for kilobytes, megabytes, etc. currently are _not_ supported ** 11 | -------------------------------------------------------------------------------- /adaptived/doc/internal/path-rules.md: -------------------------------------------------------------------------------- 1 | ## Rules for Paths in adaptived 2 | 3 | `/foo` - only operate on the `/foo` directory 4 | 5 | `/foo/` - only operate on the `/foo` directory 6 | 7 | `/foo*` - operate on `/foo` and its children 8 | 9 | `/foo/*` - only operate on `/foo`'s children 10 | -------------------------------------------------------------------------------- /adaptived/include/Makefile.am: -------------------------------------------------------------------------------- 1 | include_HEADERS = adaptived.h adaptived-utils.h 2 | -------------------------------------------------------------------------------- /adaptived/sanity-check.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright (c) 2024, Oracle and/or its affiliates. 3 | # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | # 5 | # This code is free software; you can redistribute it and/or modify it 6 | # under the terms of the GNU General Public License version 2 only, as 7 | # published by the Free Software Foundation. 8 | # 9 | # This code is distributed in the hope that it will be useful, but WITHOUT 10 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | # version 2 for more details (a copy is included in the LICENSE file that 13 | # accompanied this code). 14 | # 15 | # You should have received a copy of the GNU General Public License version 16 | # 2 along with this work; if not, write to the Free Software Foundation, 17 | # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 | # 19 | # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 | # or visit www.oracle.com if you need additional information or have any 21 | # questions. 22 | 23 | # clean up from a previous run 24 | make clean 25 | find . -name "*.gcno" -exec sudo rm '{}' \; 26 | find . -name "*.gcda" -exec sudo rm '{}' \; 27 | 28 | ./autogen.sh 29 | RET=$? 30 | 31 | if [[ $RET -ne 0 ]]; then 32 | echo "./autogen failed: " $RET 33 | exit $RET 34 | fi 35 | 36 | CFLAGS="$CFLAGS -g -O0 -Werror" ./configure 37 | RET=$? 38 | 39 | if [[ $RET -ne 0 ]]; then 40 | echo "./configure failed: " $RET 41 | exit $RET 42 | fi 43 | 44 | make distcheck 45 | RET=$? 46 | 47 | if [[ $RET -ne 0 ]]; then 48 | echo "make distcheck failed: " $RET 49 | exit $RET 50 | fi 51 | 52 | CFLAGS="$CFLAGS -g -O0 -Werror" ./configure --enable-code-coverage 53 | RET=$? 54 | 55 | if [[ $RET -ne 0 ]]; then 56 | echo "./configure w/ code coverage failed: " $RET 57 | exit $RET 58 | fi 59 | 60 | # I'm not fond of running all of the tests as root, but the sd-bus tests 61 | # need administrative privileges. Merging the non-sudo and sudo code 62 | # coverage files is difficult. Let's avoid that. 63 | sudo make check 64 | RET=$? 65 | 66 | if [[ $RET -ne 0 ]]; then 67 | echo "make check failed: " $RET 68 | exit $RET 69 | fi 70 | 71 | gcovr -s --filter src/ 72 | exit 0 73 | -------------------------------------------------------------------------------- /adaptived/src/Makefile.am: -------------------------------------------------------------------------------- 1 | @CODE_COVERAGE_RULES@ 2 | 3 | DIST_SUBDIRS = 4 | SUBDIRS = ${DIST_SUBDIRS} 5 | 6 | SOURCES = \ 7 | adaptived-internal.h \ 8 | causes/always.c \ 9 | causes/cgroup_setting.c \ 10 | causes/days_of_the_week.c \ 11 | causes/meminfo.c \ 12 | causes/memorystat.c \ 13 | causes/periodic.c \ 14 | causes/pressure.c \ 15 | causes/pressure_rate.c \ 16 | causes/slabinfo.c \ 17 | causes/time_of_day.c \ 18 | causes/top.c \ 19 | cause.c \ 20 | cause.h \ 21 | defines.h \ 22 | effects/cgroup_setting.c \ 23 | effects/cgroup_setting_by_psi.c \ 24 | effects/copy_cgroup_setting.c \ 25 | effects/kill_cgroup.c \ 26 | effects/kill_cgroup_by_psi.c \ 27 | effects/kill_processes.c \ 28 | effects/logger.c \ 29 | effects/print.c \ 30 | effects/print_schedstat.c \ 31 | effects/sd_bus_setting.c \ 32 | effects/snooze.c \ 33 | effects/validate.c \ 34 | effect.c \ 35 | effect.h \ 36 | log.c \ 37 | main.c \ 38 | parse.c \ 39 | pressure.h \ 40 | rule.c \ 41 | utils/cgroup_utils.c \ 42 | utils/sd_bus_utils.c \ 43 | utils/file_utils.c \ 44 | utils/float_utils.c \ 45 | utils/mem_utils.c \ 46 | utils/path_utils.c \ 47 | utils/pressure_utils.c \ 48 | utils/sched_utils.c 49 | 50 | adaptived_SOURCES = ${SOURCES} 51 | adaptived_CFLAGS = ${AM_CFLAGS} ${CFLAGS} ${CODE_COVERAGE_CFLAGS} -Wall 52 | adaptived_LDFLAGS = ${AM_LDFLAGS} ${LDFLAGS} ${CODE_COVERAGE_LIBS} -ljson-c -lpthread -lsystemd 53 | sbin_PROGRAMS = adaptived 54 | 55 | libadaptived_la_SOURCES = ${SOURCES} 56 | libadaptived_la_LIBADD = ${CODE_COVERAGE_LIBS} -ljson-c -lpthread -lsystemd 57 | libadaptived_la_CFLAGS = ${AM_CFLAGS} ${CFLAGS} ${CODE_COVERAGE_CFLAGS} -fPIC \ 58 | -fvisibility=hidden -Wall 59 | libadaptived_la_LDFLAGS = ${AM_LDFLAGS} ${CODE_COVERAGE_LDFLAGS} ${LDFLAGS} \ 60 | -version-number ${VERSION_MAJOR}:${VERSION_MINOR}:${VERSION_MICRO} 61 | lib_LTLIBRARIES = libadaptived.la 62 | 63 | check-build: 64 | ${MAKE} ${AM_MAKEFLAGS} ${check_PROGRAMS} 65 | -------------------------------------------------------------------------------- /adaptived/src/causes/Makefile.am: -------------------------------------------------------------------------------- 1 | SOURCES = \ 2 | time_of_day.c 3 | -------------------------------------------------------------------------------- /adaptived/src/causes/always.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. 8 | * 9 | * This code is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * version 2 for more details (a copy is included in the LICENSE file that 13 | * accompanied this code). 14 | * 15 | * You should have received a copy of the GNU General Public License version 16 | * 2 along with this work; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 | * 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 | * or visit www.oracle.com if you need additional information or have any 21 | * questions. 22 | */ 23 | /** 24 | * This cause always triggers - probably only useful in testing and debugging 25 | * 26 | */ 27 | 28 | #include "adaptived-internal.h" 29 | 30 | int always_init(struct adaptived_cause * const cse, struct json_object *args_obj, int interval) 31 | { 32 | return 0; 33 | } 34 | 35 | int always_main(struct adaptived_cause * const cse, int time_since_last_run) 36 | { 37 | /* always trigger */ 38 | return 1; 39 | } 40 | 41 | void always_exit(struct adaptived_cause * const cse) 42 | { 43 | } 44 | -------------------------------------------------------------------------------- /adaptived/src/causes/periodic.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. 8 | * 9 | * This code is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * version 2 for more details (a copy is included in the LICENSE file that 13 | * accompanied this code). 14 | * 15 | * You should have received a copy of the GNU General Public License version 16 | * 2 along with this work; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 | * 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 | * or visit www.oracle.com if you need additional information or have any 21 | * questions. 22 | */ 23 | /** 24 | * Cause that will periodically trigger. 25 | * 26 | */ 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #include 36 | #include 37 | 38 | #include "defines.h" 39 | #include "adaptived-internal.h" 40 | 41 | struct periodic_opts { 42 | /* period is in milliseconds */ 43 | int period; 44 | 45 | int current_duration; 46 | }; 47 | 48 | int periodic_init(struct adaptived_cause * const cse, struct json_object *args_obj, int interval) 49 | { 50 | struct periodic_opts *opts; 51 | int ret = 0; 52 | 53 | opts = malloc(sizeof(struct periodic_opts)); 54 | if (!opts) { 55 | ret = -ENOMEM; 56 | goto error; 57 | } 58 | 59 | memset(opts, 0, sizeof( struct periodic_opts)); 60 | 61 | ret = adaptived_parse_int(args_obj, "period", &opts->period); 62 | if (ret) 63 | goto error; 64 | 65 | ret = adaptived_cause_set_data(cse, (void *)opts); 66 | if (ret) 67 | goto error; 68 | 69 | return ret; 70 | 71 | error: 72 | if (opts) 73 | free(opts); 74 | 75 | return ret; 76 | } 77 | 78 | int periodic_main(struct adaptived_cause * const cse, int time_since_last_run) 79 | { 80 | struct periodic_opts *opts = (struct periodic_opts *)adaptived_cause_get_data(cse); 81 | 82 | opts->current_duration += time_since_last_run; 83 | 84 | if (opts->current_duration >= opts->period) { 85 | opts->current_duration = 0; 86 | /* periodic trigger */ 87 | return 1; 88 | } 89 | 90 | return 0; 91 | } 92 | 93 | void periodic_exit(struct adaptived_cause * const cse) 94 | { 95 | struct periodic_opts *opts = (struct periodic_opts *)adaptived_cause_get_data(cse); 96 | 97 | if (opts) 98 | free(opts); 99 | } 100 | -------------------------------------------------------------------------------- /adaptived/src/defines.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. 8 | * 9 | * This code is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * version 2 for more details (a copy is included in the LICENSE file that 13 | * accompanied this code). 14 | * 15 | * You should have received a copy of the GNU General Public License version 16 | * 2 along with this work; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 | * 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 | * or visit www.oracle.com if you need additional information or have any 21 | * questions. 22 | */ 23 | /** 24 | * Common definitions for adaptived 25 | * 26 | */ 27 | 28 | #ifndef __ADAPTIVED_DEFINES_H 29 | #define __ADAPTIVED_DEFINES_H 30 | 31 | #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 32 | 33 | #endif /* __ADAPTIVED_DEFINES_H */ 34 | -------------------------------------------------------------------------------- /adaptived/src/effects/snooze.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. 8 | * 9 | * This code is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * version 2 for more details (a copy is included in the LICENSE file that 13 | * accompanied this code). 14 | * 15 | * You should have received a copy of the GNU General Public License version 16 | * 2 along with this work; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 | * 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 | * or visit www.oracle.com if you need additional information or have any 21 | * questions. 22 | */ 23 | /** 24 | * snooze effect 25 | * 26 | * Some causes don't have a mechanism to ignore the cause for X seconds. 27 | * The snooze effect allows a user to ignore triggered cause(s) for the 28 | * specified duration. 29 | * 30 | */ 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | #include "adaptived-internal.h" 38 | #include "defines.h" 39 | 40 | struct snooze_opts { 41 | int duration; 42 | time_t prev_trigger; 43 | }; 44 | 45 | int snooze_init(struct adaptived_effect * const eff, struct json_object *args_obj, 46 | const struct adaptived_cause * const cse) 47 | { 48 | struct snooze_opts *opts; 49 | int ret = 0; 50 | 51 | opts = malloc(sizeof(struct snooze_opts)); 52 | if (!opts) { 53 | ret = -ENOMEM; 54 | goto error; 55 | } 56 | opts->prev_trigger = 0; 57 | 58 | ret = adaptived_parse_int(args_obj, "duration", &opts->duration); 59 | if (ret) 60 | goto error; 61 | 62 | /* we have successfully setup the snooze effect */ 63 | eff->data = (void *)opts; 64 | 65 | return ret; 66 | 67 | error: 68 | if (opts) 69 | free(opts); 70 | 71 | return ret; 72 | } 73 | 74 | int snooze_main(struct adaptived_effect * const eff) 75 | { 76 | struct snooze_opts *opts = (struct snooze_opts *)eff->data; 77 | time_t cur_time; 78 | double diff; 79 | 80 | time(&cur_time); 81 | diff = difftime(cur_time, opts->prev_trigger); 82 | adaptived_dbg("Snooze duration: %d, Current diff: %.0lf\n", opts->duration, diff); 83 | 84 | if (diff < (double)(opts->duration / 1000.0f)) 85 | /* inform adaptived to skip the remaining effects in this rule */ 86 | return -EALREADY; 87 | 88 | opts->prev_trigger = cur_time; 89 | 90 | return 0; 91 | } 92 | 93 | void snooze_exit(struct adaptived_effect * const eff) 94 | { 95 | struct snooze_opts *opts = (struct snooze_opts *)eff->data; 96 | 97 | free(opts); 98 | } 99 | -------------------------------------------------------------------------------- /adaptived/src/effects/validate.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. 8 | * 9 | * This code is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * version 2 for more details (a copy is included in the LICENSE file that 13 | * accompanied this code). 14 | * 15 | * You should have received a copy of the GNU General Public License version 16 | * 2 along with this work; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 | * 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 | * or visit www.oracle.com if you need additional information or have any 21 | * questions. 22 | */ 23 | /** 24 | * Effect to validate that a cause successfully fired 25 | * 26 | * Returns a positive integer to the main adaptived loop when 27 | * the validator main() is invoked. This will cause adaptived 28 | * to exit the main loop and can be useful for testing that 29 | * causes have executed properly 30 | * 31 | * 32 | */ 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | #include "adaptived-internal.h" 40 | #include "defines.h" 41 | 42 | const int default_return_value = 7; 43 | 44 | struct validate_opts { 45 | int ret; 46 | }; 47 | 48 | int validate_init(struct adaptived_effect * const eff, struct json_object *args_obj, 49 | const struct adaptived_cause * const cse) 50 | { 51 | struct validate_opts *opts; 52 | int ret = 0; 53 | 54 | opts = malloc(sizeof(struct validate_opts)); 55 | if (!opts) { 56 | ret = -ENOMEM; 57 | goto error; 58 | } 59 | opts->ret = default_return_value; 60 | 61 | ret = adaptived_parse_int(args_obj, "return_value", &opts->ret); 62 | if (ret) 63 | goto error; 64 | 65 | /* we have successfully setup the validate effect */ 66 | eff->data = (void *)opts; 67 | 68 | return ret; 69 | 70 | error: 71 | if (opts) 72 | free(opts); 73 | 74 | return ret; 75 | } 76 | 77 | int validate_main(struct adaptived_effect * const eff) 78 | { 79 | struct validate_opts *opts = (struct validate_opts *)eff->data; 80 | 81 | /* main() will negate our return value */ 82 | return -opts->ret; 83 | } 84 | 85 | void validate_exit(struct adaptived_effect * const eff) 86 | { 87 | struct validate_opts *opts = (struct validate_opts *)eff->data; 88 | 89 | free(opts); 90 | } 91 | -------------------------------------------------------------------------------- /adaptived/src/log.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. 8 | * 9 | * This code is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * version 2 for more details (a copy is included in the LICENSE file that 13 | * accompanied this code). 14 | * 15 | * You should have received a copy of the GNU General Public License version 16 | * 2 along with this work; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 | * 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 | * or visit www.oracle.com if you need additional information or have any 21 | * questions. 22 | */ 23 | /** 24 | * Logging for adaptived 25 | * 26 | */ 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include "adaptived-internal.h" 35 | 36 | int log_level = LOG_ERR; 37 | enum log_location log_loc = LOG_LOC_STDERR; 38 | 39 | static void _log(int priority, const char *fmt, va_list *ap) 40 | { 41 | switch(log_loc) { 42 | case LOG_LOC_JOURNAL: 43 | sd_journal_printv(priority, fmt, *ap); 44 | break; 45 | case LOG_LOC_SYSLOG: 46 | vsyslog(priority, fmt, *ap); 47 | break; 48 | case LOG_LOC_STDOUT: 49 | vfprintf(stdout, fmt, *ap); 50 | break; 51 | case LOG_LOC_STDERR: 52 | vfprintf(stderr, fmt, *ap); 53 | break; 54 | default: 55 | assert(true); 56 | break; 57 | } 58 | va_end(*ap); 59 | } 60 | 61 | API void adaptived_err(const char *fmt, ...) 62 | { 63 | va_list ap; 64 | 65 | if (log_level >= LOG_ERR) { 66 | va_start(ap, fmt); 67 | _log(LOG_ERR, fmt, &ap); 68 | va_end(ap); 69 | } 70 | } 71 | 72 | API void adaptived_wrn(const char *fmt, ...) 73 | { 74 | va_list ap; 75 | 76 | if (log_level >= LOG_WARNING) { 77 | va_start(ap, fmt); 78 | _log(LOG_WARNING, fmt, &ap); 79 | va_end(ap); 80 | } 81 | } 82 | 83 | API void adaptived_info(const char *fmt, ...) 84 | { 85 | va_list ap; 86 | 87 | if (log_level >= LOG_INFO) { 88 | va_start(ap, fmt); 89 | _log(LOG_INFO, fmt, &ap); 90 | va_end(ap); 91 | } 92 | } 93 | 94 | API void adaptived_dbg(const char *fmt, ...) 95 | { 96 | va_list ap; 97 | 98 | if (log_level >= LOG_DEBUG) { 99 | va_start(ap, fmt); 100 | _log(LOG_DEBUG, fmt, &ap); 101 | va_end(ap); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /adaptived/src/utils/Makefile.am: -------------------------------------------------------------------------------- 1 | @CODE_COVERAGE_RULES@ 2 | 3 | EXTRA_DIST = \ 4 | pressure_utils.c \ 5 | pressure_utils.h 6 | -------------------------------------------------------------------------------- /adaptived/src/utils/float_utils.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. 8 | * 9 | * This code is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * version 2 for more details (a copy is included in the LICENSE file that 13 | * accompanied this code). 14 | * 15 | * You should have received a copy of the GNU General Public License version 16 | * 2 along with this work; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 | * 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 | * or visit www.oracle.com if you need additional information or have any 21 | * questions. 22 | */ 23 | /** 24 | * Utilities for managing arrays of floats 25 | * 26 | */ 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | #include 33 | #include 34 | 35 | #include "adaptived-internal.h" 36 | 37 | API int adaptived_farray_append(float * const array, const float * const value, int array_len, 38 | int * const samples_in_array) 39 | { 40 | if (!array || !value || !samples_in_array || array_len <= 0) 41 | return -EINVAL; 42 | 43 | if (*samples_in_array > array_len) 44 | return -EINVAL; 45 | 46 | if (*samples_in_array < array_len) { 47 | array[*samples_in_array] = *value; 48 | (*samples_in_array)++; 49 | } else { 50 | memmove(array, &array[1], sizeof(float) * (array_len - 1)); 51 | array[array_len - 1] = *value; 52 | } 53 | 54 | return 0; 55 | } 56 | 57 | API int adaptived_farray_linear_regression(float * const array, int array_len, int interval, 58 | int interp_x, float * const interp_y) 59 | { 60 | float xmean, ymean, numer, denom, intercept, slope; 61 | int i; 62 | 63 | if (!array || !interp_y) 64 | return -EINVAL; 65 | if (array_len <= 0 || interval <= 0) 66 | return -EINVAL; 67 | 68 | xmean = 0.0f; 69 | ymean = 0.0f; 70 | for (i = 0; i < array_len; i++) { 71 | ymean += array[i]; 72 | xmean += (float)((i + 1) * interval); 73 | } 74 | 75 | ymean = ymean / array_len; 76 | xmean = xmean / array_len; 77 | 78 | numer = 0.0f; 79 | denom = 0.0f; 80 | for (i = 0; i < array_len; i++) { 81 | numer += (((i + 1) * interval) - xmean) * (array[i] - ymean); 82 | denom += (((i + 1) * interval) - xmean) * (((i + 1) * interval) - xmean); 83 | } 84 | 85 | slope = numer / denom; 86 | intercept = ymean - (slope * xmean); 87 | adaptived_dbg("LinInterp: slope = %.2f yintcpt = %.2f\n", slope, intercept); 88 | 89 | *interp_y = (slope * ((array_len * interval) + interp_x)) + intercept; 90 | adaptived_dbg("LinInterp: interp_y = %.2f\n", *interp_y); 91 | 92 | return 0; 93 | } 94 | -------------------------------------------------------------------------------- /adaptived/tests/Makefile.am: -------------------------------------------------------------------------------- 1 | @CODE_COVERAGE_RULES@ 2 | 3 | DIST_SUBDIRS = ftests gunit 4 | SUBDIRS = $(DIST_SUBDIRS) 5 | 6 | check-build: 7 | ${MAKE} ${AM_MAKEFLAGS} -C ftests check-build 8 | ${MAKE} ${AM_MAKEFLAGS} -C gunit check-build 9 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__/ 2 | *.log 3 | *.pressure 4 | *.trs 5 | test[0-9]* 6 | sudo1[0-9]* 7 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/001-cause-time_of_day.json.token: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Time-of-Day test. Should trip", 5 | "causes": [ 6 | { 7 | "name": "time_of_day", 8 | "args": { 9 | "time": "<< now + 3 >>", 10 | "operator": "greaterthan" 11 | } 12 | } 13 | ], 14 | "effects": [ 15 | { 16 | "name": "validate", 17 | "args": { 18 | "return_value": 42 19 | } 20 | } 21 | ] 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/001-cause-time_of_day.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Copyright (c) 2024, Oracle and/or its affiliates. 3 | # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | # 5 | # This code is free software; you can redistribute it and/or modify it 6 | # under the terms of the GNU General Public License version 2 only, as 7 | # published by the Free Software Foundation. 8 | # 9 | # This code is distributed in the hope that it will be useful, but WITHOUT 10 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | # version 2 for more details (a copy is included in the LICENSE file that 13 | # accompanied this code). 14 | # 15 | # You should have received a copy of the GNU General Public License version 16 | # 2 along with this work; if not, write to the Free Software Foundation, 17 | # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 | # 19 | # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 | # or visit www.oracle.com if you need additional information or have any 21 | # questions. 22 | 23 | # 24 | # Test the time-of-day cause 25 | # 26 | # 27 | 28 | import adaptived 29 | import consts 30 | 31 | CONFIG = '001-cause-time_of_day.json.token' 32 | INTERVAL = 1000 33 | MAX_LOOPS = 10 34 | EXPECTED_RET = 42 35 | 36 | def prereqs(config): 37 | result = consts.TEST_PASSED 38 | cause = None 39 | 40 | return result, cause 41 | 42 | 43 | def setup(config): 44 | pass 45 | 46 | 47 | def test(config): 48 | result = consts.TEST_PASSED 49 | cause = None 50 | 51 | adaptived.adaptived(config=CONFIG, interval=INTERVAL, max_loops=MAX_LOOPS, 52 | expected_ret=EXPECTED_RET) 53 | return result, cause 54 | 55 | 56 | def teardown(config): 57 | pass 58 | 59 | 60 | def main(config): 61 | [result, cause] = prereqs(config) 62 | if result != consts.TEST_PASSED: 63 | return [result, cause] 64 | 65 | try: 66 | setup(config) 67 | [result, cause] = test(config) 68 | finally: 69 | teardown(config) 70 | 71 | return [result, cause] 72 | 73 | 74 | if __name__ == '__main__': 75 | config = ftests.parse_args() 76 | # this test was invoked directly. run only it 77 | config.args.num = int(os.path.basename(__file__).split('-')[0]) 78 | sys.exit(ftests.main(config)) 79 | 80 | # vim: set et ts=4 sw=4: 81 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/002-register_cause.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Wait for 6 cycles in total. Should trip", 5 | "causes": [ 6 | { 7 | "name": "wait_cause", 8 | "args": { 9 | "wait": 2 10 | } 11 | }, 12 | { 13 | "name": "wait_cause", 14 | "args": { 15 | "wait": 5 16 | } 17 | }, 18 | { 19 | "name": "wait_cause", 20 | "args": { 21 | "wait": 6 22 | } 23 | } 24 | ], 25 | "effects": [ 26 | { 27 | "name": "validate", 28 | "args": { 29 | "return_value": 123 30 | } 31 | } 32 | ] 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/003-register_plugin_cause.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. 8 | * 9 | * This code is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * version 2 for more details (a copy is included in the LICENSE file that 13 | * accompanied this code). 14 | * 15 | * You should have received a copy of the GNU General Public License version 16 | * 2 along with this work; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 | * 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 | * or visit www.oracle.com if you need additional information or have any 21 | * questions. 22 | */ 23 | /** 24 | * Test to register a cause at runtime and utilize it 25 | * 26 | */ 27 | 28 | #include 29 | #include 30 | 31 | #include 32 | 33 | #include "ftests.h" 34 | 35 | #define EXPECTED_RET -123 36 | 37 | int main(int argc, char *argv[]) 38 | { 39 | char config_path[FILENAME_MAX]; 40 | struct adaptived_ctx *ctx; 41 | int ret; 42 | 43 | snprintf(config_path, FILENAME_MAX - 1, "%s/003-register_plugin_cause.json", argv[1]); 44 | config_path[FILENAME_MAX - 1] = '\0'; 45 | 46 | ctx = adaptived_init(config_path); 47 | if (!ctx) 48 | return AUTOMAKE_HARD_ERROR; 49 | 50 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_MAX_LOOPS, 10); 51 | if (ret) 52 | goto err; 53 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_INTERVAL, 1000); 54 | if (ret) 55 | goto err; 56 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_SKIP_SLEEP, 1); 57 | if (ret) 58 | goto err; 59 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_LOG_LEVEL, LOG_INFO); 60 | if (ret) 61 | goto err; 62 | 63 | ret = adaptived_register_cause(ctx, tod_name, &tod_fns); 64 | if (ret) 65 | goto err; 66 | 67 | ret = adaptived_loop(ctx, true); 68 | if (ret != EXPECTED_RET) 69 | goto err; 70 | 71 | adaptived_release(&ctx); 72 | return AUTOMAKE_PASSED; 73 | 74 | err: 75 | adaptived_release(&ctx); 76 | return AUTOMAKE_HARD_ERROR; 77 | } 78 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/003-register_plugin_cause.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Wait for 6 cycles in total. Should trip", 5 | "causes": [ 6 | { 7 | "name": "tod", 8 | "args": { 9 | "time": "00:00:05", 10 | "operator": "greaterthan" 11 | } 12 | } 13 | ], 14 | "effects": [ 15 | { 16 | "name": "print", 17 | "args": { 18 | "file": "stdout", 19 | "message": "Test 003 tripped successfully\n" 20 | } 21 | }, 22 | { 23 | "name": "validate", 24 | "args": { 25 | "return_value": 123 26 | } 27 | } 28 | ] 29 | } 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/004-register_plugin_effect.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. 8 | * 9 | * This code is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * version 2 for more details (a copy is included in the LICENSE file that 13 | * accompanied this code). 14 | * 15 | * You should have received a copy of the GNU General Public License version 16 | * 2 along with this work; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 | * 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 | * or visit www.oracle.com if you need additional information or have any 21 | * questions. 22 | */ 23 | /** 24 | * Test to register a effect at runtime and utilize it 25 | * 26 | */ 27 | 28 | #include 29 | 30 | #include 31 | 32 | #include "ftests.h" 33 | 34 | #define EXPECTED_RET -123 35 | 36 | int main(int argc, char *argv[]) 37 | { 38 | char config_path[FILENAME_MAX]; 39 | struct adaptived_ctx *ctx; 40 | int ret; 41 | 42 | snprintf(config_path, FILENAME_MAX - 1, "%s/004-register_plugin_effect.json", argv[1]); 43 | config_path[FILENAME_MAX - 1] = '\0'; 44 | ctx = adaptived_init(config_path); 45 | if (!ctx) 46 | return AUTOMAKE_HARD_ERROR; 47 | 48 | if (argc == 3) { 49 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_LOG_LEVEL, atoi(argv[2])); 50 | if (ret) 51 | goto err; 52 | } 53 | 54 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_MAX_LOOPS, 10); 55 | if (ret) 56 | goto err; 57 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_INTERVAL, 1000); 58 | if (ret) 59 | goto err; 60 | 61 | ret = adaptived_register_cause(ctx, tod_name, &tod_fns); 62 | if (ret) 63 | goto err; 64 | ret = adaptived_register_effect(ctx, tod_validate_name, &tod_validate_fns); 65 | if (ret) 66 | goto err; 67 | 68 | ret = adaptived_loop(ctx, true); 69 | if (ret != EXPECTED_RET) 70 | goto err; 71 | 72 | adaptived_release(&ctx); 73 | return AUTOMAKE_PASSED; 74 | 75 | err: 76 | adaptived_release(&ctx); 77 | return AUTOMAKE_HARD_ERROR; 78 | } 79 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/004-register_plugin_effect.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Wait for 6 cycles in total. Should trip", 5 | "causes": [ 6 | { 7 | "name": "tod", 8 | "args": { 9 | "time": "00:00:04", 10 | "operator": "greaterthan" 11 | } 12 | }, 13 | { 14 | "name": "days_of_the_week", 15 | "args": { 16 | "days": [ 17 | { 18 | "day": "sunday" 19 | }, 20 | { 21 | "day": "monday" 22 | }, 23 | { 24 | "day": "tuesday" 25 | }, 26 | { 27 | "day": "wednesday" 28 | }, 29 | { 30 | "day": "thursday" 31 | }, 32 | { 33 | "day": "friday" 34 | }, 35 | { 36 | "day": "saturday" 37 | } 38 | ] 39 | } 40 | } 41 | ], 42 | "effects": [ 43 | { 44 | "name": "tod_validate", 45 | "args": { 46 | "return_value": 123 47 | } 48 | } 49 | ] 50 | } 51 | ] 52 | } 53 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/007-cause-avg300_pressure_above.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "pressure above test.", 5 | "causes": [ 6 | { 7 | "name": "pressure", 8 | "args": { 9 | "pressure_file": "007-cause-avg300_pressure_above.pressure", 10 | "threshold": 50, 11 | "duration": 3, 12 | "operator": "greaterthan", 13 | "measurement": "some-avg300" 14 | } 15 | } 16 | ], 17 | "effects": [ 18 | { 19 | "name": "validate", 20 | "args": { 21 | "return_value": 42 22 | } 23 | } 24 | ] 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/008-cause-pressure_above_total.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "pressure above test.", 5 | "causes": [ 6 | { 7 | "name": "pressure", 8 | "args": { 9 | "pressure_file": "008-cause-pressure_above_total.pressure", 10 | "threshold": 1234567890, 11 | "duration": 3, 12 | "operator": "greaterthan", 13 | "measurement": "full-total" 14 | } 15 | } 16 | ], 17 | "effects": [ 18 | { 19 | "name": "validate", 20 | "args": { 21 | "return_value": 43 22 | } 23 | } 24 | ] 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/009-cause-pressure_below.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "pressure below test.", 5 | "causes": [ 6 | { 7 | "name": "pressure", 8 | "args": { 9 | "pressure_file": "009-cause-pressure_below.pressure", 10 | "threshold": 33.3, 11 | "duration": 5, 12 | "operator": "lessthan", 13 | "measurement": "some-avg10" 14 | } 15 | } 16 | ], 17 | "effects": [ 18 | { 19 | "name": "validate", 20 | "args": { 21 | "return_value": 44 22 | } 23 | } 24 | ] 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/010-snooze_effect.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. 8 | * 9 | * This code is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * version 2 for more details (a copy is included in the LICENSE file that 13 | * accompanied this code). 14 | * 15 | * You should have received a copy of the GNU General Public License version 16 | * 2 along with this work; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 | * 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 | * or visit www.oracle.com if you need additional information or have any 21 | * questions. 22 | */ 23 | /** 24 | * Test to register a cause at runtime and utilize it 25 | * 26 | */ 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | #include 33 | 34 | #include "ftests.h" 35 | 36 | int main(int argc, char *argv[]) 37 | { 38 | struct adaptived_rule_stats stats; 39 | char config_path[FILENAME_MAX]; 40 | struct adaptived_ctx *ctx; 41 | int ret; 42 | 43 | snprintf(config_path, FILENAME_MAX - 1, "%s/010-snooze_effect.json", argv[1]); 44 | config_path[FILENAME_MAX - 1] = '\0'; 45 | 46 | ctx = adaptived_init(config_path); 47 | if (!ctx) 48 | return AUTOMAKE_HARD_ERROR; 49 | 50 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_MAX_LOOPS, 6); 51 | if (ret) 52 | goto err; 53 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_INTERVAL, 1000); 54 | if (ret) 55 | goto err; 56 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_LOG_LEVEL, LOG_DEBUG); 57 | if (ret) 58 | goto err; 59 | 60 | ret = adaptived_loop(ctx, true); 61 | if (ret != -ETIME) 62 | goto err; 63 | 64 | /* we want the trigger count for rule 0 */ 65 | ret = adaptived_get_rule_stats(ctx, "Ensure the snooze effect silences effects as expected", 66 | &stats); 67 | if (ret != 0) 68 | goto err; 69 | 70 | if (stats.trigger_cnt != 6) 71 | goto err; 72 | if (stats.snooze_cnt != 4) 73 | goto err; 74 | 75 | adaptived_release(&ctx); 76 | return AUTOMAKE_PASSED; 77 | 78 | err: 79 | adaptived_release(&ctx); 80 | return AUTOMAKE_HARD_ERROR; 81 | } 82 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/010-snooze_effect.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Ensure the snooze effect silences effects as expected", 5 | "causes": [ 6 | { 7 | "name": "time_of_day", 8 | "args": { 9 | "time": "00:00:01", 10 | "operator": "greaterthan" 11 | } 12 | } 13 | ], 14 | "effects": [ 15 | { 16 | "name": "snooze", 17 | "args": { 18 | "duration": 4000 19 | } 20 | } 21 | ] 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/011-cause-pressure_rate_rising.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "pressure rising above test.", 5 | "causes": [ 6 | { 7 | "name": "pressure_rate", 8 | "args": { 9 | "pressure_file": "011-cause-pressure_rate_rising.pressure", 10 | "threshold": 53.5, 11 | "window_size": 30000, 12 | "action": "rising", 13 | "advanced_warning": 10000, 14 | "measurement": "full-avg60" 15 | } 16 | } 17 | ], 18 | "effects": [ 19 | { 20 | "name": "validate", 21 | "args": { 22 | "return_value": 64 23 | } 24 | } 25 | ] 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/012-cause-pressure_rate_falling.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "pressure falling below test.", 5 | "causes": [ 6 | { 7 | "name": "pressure_rate", 8 | "args": { 9 | "pressure_file": "012-cause-pressure_rate_falling.pressure", 10 | "threshold": 80.0, 11 | "action": "falling", 12 | "measurement": "some-avg10" 13 | } 14 | } 15 | ], 16 | "effects": [ 17 | { 18 | "name": "validate", 19 | "args": { 20 | "return_value": 72 21 | } 22 | } 23 | ] 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/013-adaptived-asynchronous_loop.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Empty set of rules. Will never trigger", 5 | "causes": [ 6 | ], 7 | "effects": [ 8 | ] 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/019-effect-cgroup_setting_set_int.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. 8 | * 9 | * This code is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * version 2 for more details (a copy is included in the LICENSE file that 13 | * accompanied this code). 14 | * 15 | * You should have received a copy of the GNU General Public License version 16 | * 2 along with this work; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 | * 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 | * or visit www.oracle.com if you need additional information or have any 21 | * questions. 22 | */ 23 | /** 24 | * Test to set a cgroup integer setting 25 | * 26 | */ 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include 34 | 35 | #include "ftests.h" 36 | 37 | #define EXPECTED_RET -ETIME 38 | 39 | static const char * const cgroup_file = "./test019.cgroup"; 40 | static const int expected_value = 2468; 41 | 42 | int main(int argc, char *argv[]) 43 | { 44 | char config_path[FILENAME_MAX]; 45 | struct adaptived_ctx *ctx = NULL; 46 | int ret; 47 | 48 | snprintf(config_path, FILENAME_MAX - 1, "%s/019-effect-cgroup_setting_set_int.json", argv[1]); 49 | config_path[FILENAME_MAX - 1] = '\0'; 50 | 51 | ctx = adaptived_init(config_path); 52 | if (!ctx) 53 | return AUTOMAKE_HARD_ERROR; 54 | 55 | write_file(cgroup_file, "13579"); 56 | 57 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_MAX_LOOPS, 1); 58 | if (ret) 59 | goto err; 60 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_INTERVAL, 3000); 61 | if (ret) 62 | goto err; 63 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_SKIP_SLEEP, 1); 64 | if (ret) 65 | goto err; 66 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_LOG_LEVEL, LOG_DEBUG); 67 | if (ret) 68 | goto err; 69 | 70 | ret = adaptived_loop(ctx, true); 71 | if (ret != EXPECTED_RET) 72 | goto err; 73 | 74 | ret = verify_int_file(cgroup_file, expected_value); 75 | if (ret) 76 | goto err; 77 | 78 | delete_file(cgroup_file); 79 | adaptived_release(&ctx); 80 | 81 | return AUTOMAKE_PASSED; 82 | 83 | err: 84 | delete_file(cgroup_file); 85 | adaptived_release(&ctx); 86 | 87 | return AUTOMAKE_HARD_ERROR; 88 | } 89 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/019-effect-cgroup_setting_set_int.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Set an integer cgroup setting", 5 | "causes": [ 6 | { 7 | "name": "always", 8 | "args": { 9 | } 10 | } 11 | ], 12 | "effects": [ 13 | { 14 | "name": "cgroup_setting", 15 | "args": { 16 | "setting": "./test019.cgroup", 17 | "value": 2468, 18 | "operator": "set" 19 | } 20 | } 21 | ] 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/020-effect-cgroup_setting_add_int.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. 8 | * 9 | * This code is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * version 2 for more details (a copy is included in the LICENSE file that 13 | * accompanied this code). 14 | * 15 | * You should have received a copy of the GNU General Public License version 16 | * 2 along with this work; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 | * 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 | * or visit www.oracle.com if you need additional information or have any 21 | * questions. 22 | */ 23 | /** 24 | * Test to add to a cgroup integer setting 25 | * 26 | */ 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include 34 | 35 | #include "ftests.h" 36 | 37 | #define EXPECTED_RET -ETIME 38 | 39 | static const char * const cgroup_file = "./test020.cgroup"; 40 | static const int expected_value = 627; 41 | 42 | int main(int argc, char *argv[]) 43 | { 44 | char config_path[FILENAME_MAX]; 45 | struct adaptived_ctx *ctx = NULL; 46 | int ret; 47 | 48 | snprintf(config_path, FILENAME_MAX - 1, "%s/020-effect-cgroup_setting_add_int.json", argv[1]); 49 | config_path[FILENAME_MAX - 1] = '\0'; 50 | 51 | ctx = adaptived_init(config_path); 52 | if (!ctx) 53 | return AUTOMAKE_HARD_ERROR; 54 | 55 | write_file(cgroup_file, "100"); 56 | 57 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_MAX_LOOPS, 500); 58 | if (ret) 59 | goto err; 60 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_INTERVAL, 3000); 61 | if (ret) 62 | goto err; 63 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_SKIP_SLEEP, 1); 64 | if (ret) 65 | goto err; 66 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_LOG_LEVEL, LOG_INFO); 67 | if (ret) 68 | goto err; 69 | 70 | ret = adaptived_loop(ctx, true); 71 | if (ret != EXPECTED_RET) 72 | goto err; 73 | 74 | ret = verify_int_file(cgroup_file, expected_value); 75 | if (ret) 76 | goto err; 77 | 78 | delete_file(cgroup_file); 79 | adaptived_release(&ctx); 80 | 81 | return AUTOMAKE_PASSED; 82 | 83 | err: 84 | delete_file(cgroup_file); 85 | adaptived_release(&ctx); 86 | 87 | return AUTOMAKE_HARD_ERROR; 88 | } 89 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/020-effect-cgroup_setting_add_int.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Add to an integer cgroup setting", 5 | "causes": [ 6 | { 7 | "name": "always", 8 | "args": { 9 | } 10 | } 11 | ], 12 | "effects": [ 13 | { 14 | "name": "cgroup_setting", 15 | "args": { 16 | "setting": "./test020.cgroup", 17 | "value": 5, 18 | "operator": "add", 19 | "limit": 627, 20 | "validate": false 21 | } 22 | } 23 | ] 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/021-effect-cgroup_setting_sub_int.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. 8 | * 9 | * This code is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * version 2 for more details (a copy is included in the LICENSE file that 13 | * accompanied this code). 14 | * 15 | * You should have received a copy of the GNU General Public License version 16 | * 2 along with this work; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 | * 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 | * or visit www.oracle.com if you need additional information or have any 21 | * questions. 22 | */ 23 | /** 24 | * Test to subtract from a cgroup integer setting 25 | * 26 | */ 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include 34 | 35 | #include "ftests.h" 36 | 37 | #define EXPECTED_RET -ETIME 38 | 39 | static const char * const cgroup_file = "./test021.cgroup"; 40 | static const int expected_value = 987654; 41 | 42 | int main(int argc, char *argv[]) 43 | { 44 | char config_path[FILENAME_MAX]; 45 | struct adaptived_ctx *ctx = NULL; 46 | int ret; 47 | 48 | snprintf(config_path, FILENAME_MAX - 1, "%s/021-effect-cgroup_setting_sub_int.json", argv[1]); 49 | config_path[FILENAME_MAX - 1] = '\0'; 50 | 51 | ctx = adaptived_init(config_path); 52 | if (!ctx) 53 | return AUTOMAKE_HARD_ERROR; 54 | 55 | write_file(cgroup_file, "1024000"); 56 | 57 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_MAX_LOOPS, 2000); 58 | if (ret) 59 | goto err; 60 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_INTERVAL, 6000); 61 | if (ret) 62 | goto err; 63 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_SKIP_SLEEP, 1); 64 | if (ret) 65 | goto err; 66 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_LOG_LEVEL, LOG_WARNING); 67 | if (ret) 68 | goto err; 69 | 70 | ret = adaptived_loop(ctx, true); 71 | if (ret != EXPECTED_RET) { 72 | adaptived_err("Test 021 returned: %d, expected: %d\n", ret, EXPECTED_RET); 73 | goto err; 74 | } 75 | 76 | ret = verify_int_file(cgroup_file, expected_value); 77 | if (ret) 78 | goto err; 79 | 80 | delete_file(cgroup_file); 81 | adaptived_release(&ctx); 82 | 83 | return AUTOMAKE_PASSED; 84 | 85 | err: 86 | delete_file(cgroup_file); 87 | adaptived_release(&ctx); 88 | 89 | return AUTOMAKE_HARD_ERROR; 90 | } 91 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/021-effect-cgroup_setting_sub_int.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Subtract from an integer cgroup setting", 5 | "causes": [ 6 | { 7 | "name": "always", 8 | "args": { 9 | } 10 | } 11 | ], 12 | "effects": [ 13 | { 14 | "name": "cgroup_setting", 15 | "args": { 16 | "setting": "./test021.cgroup", 17 | "value": 1024, 18 | "operator": "subtract", 19 | "limit": 987654, 20 | "validate": true 21 | } 22 | } 23 | ] 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/022-effect-kill_cgroup.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. 8 | * 9 | * This code is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * version 2 for more details (a copy is included in the LICENSE file that 13 | * accompanied this code). 14 | * 15 | * You should have received a copy of the GNU General Public License version 16 | * 2 along with this work; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 | * 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 | * or visit www.oracle.com if you need additional information or have any 21 | * questions. 22 | */ 23 | /** 24 | * Test to exercise the kill cgroup effect 25 | * 26 | */ 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | #include 38 | 39 | #include "ftests.h" 40 | 41 | #define EXPECTED_RET -ETIME 42 | 43 | static const char * const cgroup_dir = "./test022cgroup"; 44 | static const char * const cgroup_file = "./test022cgroup/cgroup.procs"; 45 | 46 | #define PID_COUNT 6 47 | static pid_t pids[PID_COUNT]; 48 | 49 | static void write_cgroup_procs(void) 50 | { 51 | char buf[1024] = { '\0' }; 52 | char pid[16]; 53 | int i; 54 | 55 | for (i = 0; i < PID_COUNT; i++) { 56 | memset(pid, 0, sizeof(pid)); 57 | sprintf(pid, "%d\n", pids[i]); 58 | strcat(buf, pid); 59 | } 60 | 61 | write_file(cgroup_file, buf); 62 | } 63 | 64 | int main(int argc, char *argv[]) 65 | { 66 | char config_path[FILENAME_MAX]; 67 | struct adaptived_ctx *ctx = NULL; 68 | int ret; 69 | 70 | snprintf(config_path, FILENAME_MAX - 1, "%s/022-effect-kill_cgroup.json", argv[1]); 71 | config_path[FILENAME_MAX - 1] = '\0'; 72 | 73 | ctx = adaptived_init(config_path); 74 | if (!ctx) 75 | return AUTOMAKE_HARD_ERROR; 76 | 77 | ret = create_dir(cgroup_dir); 78 | if (ret) 79 | goto err; 80 | ret = create_pids(pids, PID_COUNT, DEFAULT_SLEEP); 81 | if (ret) 82 | goto err; 83 | write_cgroup_procs(); 84 | 85 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_MAX_LOOPS, 2); 86 | if (ret) 87 | goto err; 88 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_INTERVAL, 7000); 89 | if (ret) 90 | goto err; 91 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_SKIP_SLEEP, 1); 92 | if (ret) 93 | goto err; 94 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_LOG_LEVEL, LOG_INFO); 95 | if (ret) 96 | goto err; 97 | 98 | ret = adaptived_loop(ctx, true); 99 | if (ret != EXPECTED_RET) { 100 | adaptived_err("Test 022 returned: %d, expected: %d\n", ret, EXPECTED_RET); 101 | goto err; 102 | } 103 | 104 | wait_for_pids(pids, PID_COUNT); 105 | 106 | ret = verify_pids_were_killed(pids, PID_COUNT); 107 | if (ret) 108 | goto err; 109 | 110 | delete_file(cgroup_file); 111 | rmdir(cgroup_dir); 112 | adaptived_release(&ctx); 113 | 114 | return AUTOMAKE_PASSED; 115 | 116 | err: 117 | delete_file(cgroup_file); 118 | rmdir(cgroup_dir); 119 | adaptived_release(&ctx); 120 | 121 | return AUTOMAKE_HARD_ERROR; 122 | } 123 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/022-effect-kill_cgroup.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Kill all processes in a cgroup", 5 | "causes": [ 6 | { 7 | "name": "always", 8 | "args": { 9 | } 10 | } 11 | ], 12 | "effects": [ 13 | { 14 | "name": "kill_cgroup", 15 | "args": { 16 | "cgroup": "./test022cgroup" 17 | } 18 | } 19 | ] 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/023-effect-kill_cgroup_recursive.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Recursively kill processes in a cgroup hierarchy", 5 | "causes": [ 6 | { 7 | "name": "always", 8 | "args": { 9 | } 10 | } 11 | ], 12 | "effects": [ 13 | { 14 | "name": "kill_cgroup", 15 | "args": { 16 | "cgroup": "./test023cgroup*" 17 | } 18 | } 19 | ] 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/024-effect-kill_cgroup_by_psi.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Kill cgroup with highest psi usage", 5 | "causes": [ 6 | { 7 | "name": "always", 8 | "args": { 9 | } 10 | } 11 | ], 12 | "effects": [ 13 | { 14 | "name": "kill_cgroup_by_psi", 15 | "args": { 16 | "cgroup": "./test024cgroup*", 17 | "measurement": "some-avg10", 18 | "type": "cpu" 19 | } 20 | } 21 | ] 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/025-effect-cgroup_setting_by_psi_1.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Reduce memory.high in the cgroup with lowest psi usage", 5 | "causes": [ 6 | { 7 | "name": "always", 8 | "args": { 9 | } 10 | } 11 | ], 12 | "effects": [ 13 | { 14 | "name": "cgroup_setting_by_psi", 15 | "args": { 16 | "cgroup": "./test025cgroup*", 17 | "type": "memory", 18 | "measurement": "full-avg300", 19 | "pressure_operator": "lessthan", 20 | "setting": "memory.high", 21 | "value": 1, 22 | "setting_operator": "subtract", 23 | "limit": 998, 24 | "validate": true 25 | } 26 | } 27 | ] 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/026-effect-cgroup_setting_by_psi_2.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Increase memory.high in the cgroup with highest psi usage", 5 | "causes": [ 6 | { 7 | "name": "always", 8 | "args": { 9 | } 10 | } 11 | ], 12 | "effects": [ 13 | { 14 | "name": "cgroup_setting_by_psi", 15 | "args": { 16 | "cgroup": "./test026cgroup*", 17 | "type": "memory", 18 | "measurement": "full-avg300", 19 | "pressure_operator": "greaterthan", 20 | "setting": "memory.high", 21 | "value": 1, 22 | "setting_operator": "add", 23 | "limit": 1003, 24 | "validate": true 25 | } 26 | } 27 | ] 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/027-effect-cgroup_setting_by_psi_3.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Set cpu.shares in the cgroup with highest psi usage", 5 | "causes": [ 6 | { 7 | "name": "always", 8 | "args": { 9 | } 10 | } 11 | ], 12 | "effects": [ 13 | { 14 | "name": "cgroup_setting_by_psi", 15 | "args": { 16 | "cgroup": "./test027cgroup*", 17 | "type": "cpu", 18 | "measurement": "some-avg60", 19 | "pressure_operator": "greaterthan", 20 | "setting": "cpu.weight", 21 | "value": 75, 22 | "setting_operator": "set" 23 | } 24 | } 25 | ] 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/028-effect-copy_cgroup_setting.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "copy cgroup setting", 5 | "causes": [ 6 | { 7 | "name": "always", 8 | "args": { 9 | } 10 | } 11 | ], 12 | "effects": [ 13 | { 14 | "name": "copy_cgroup_setting", 15 | "args": { 16 | "from_setting": "./test028_from.cgroup", 17 | "to_setting": "./test028_to.cgroup", 18 | "dont_copy_if_zero": true, 19 | "validate": true 20 | } 21 | } 22 | ] 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/029-cause-cgroup_setting_ll_gt.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Cgroup long long setting > threshold", 5 | "causes": [ 6 | { 7 | "name": "cgroup_setting", 8 | "args": { 9 | "setting": "029-cause-cgroup_setting.setting", 10 | "threshold": 5, 11 | "operator": "greaterthan" 12 | } 13 | } 14 | ], 15 | "effects": [ 16 | { 17 | "name": "validate", 18 | "args": { 19 | "return_value": 65 20 | } 21 | } 22 | ] 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/030-cause-cgroup_setting_ll_lt.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Cgroup long long setting < threshold", 5 | "causes": [ 6 | { 7 | "name": "cgroup_setting", 8 | "args": { 9 | "setting": "030-cause-cgroup_setting.setting", 10 | "threshold": 6000, 11 | "operator": "lessthan" 12 | } 13 | } 14 | ], 15 | "effects": [ 16 | { 17 | "name": "validate", 18 | "args": { 19 | "return_value": 66 20 | } 21 | } 22 | ] 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/031-cause-cgroup_setting_float_gt.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Cgroup float setting > threshold", 5 | "causes": [ 6 | { 7 | "name": "cgroup_setting", 8 | "args": { 9 | "setting": "031-cause-cgroup_setting.setting", 10 | "threshold": 42.51, 11 | "operator": "greaterthan" 12 | } 13 | } 14 | ], 15 | "effects": [ 16 | { 17 | "name": "validate", 18 | "args": { 19 | "return_value": 67 20 | } 21 | } 22 | ] 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/032-cause-cgroup_setting_float_lt.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Cgroup float setting < threshold", 5 | "causes": [ 6 | { 7 | "name": "cgroup_setting", 8 | "args": { 9 | "setting": "032-cause-cgroup_setting.setting", 10 | "threshold": 1.9945, 11 | "operator": "lessthan" 12 | } 13 | } 14 | ], 15 | "effects": [ 16 | { 17 | "name": "validate", 18 | "args": { 19 | "return_value": 68 20 | } 21 | } 22 | ] 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/033-validate_humanize.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "copy cgroup setting", 5 | "causes": [ 6 | { 7 | "name": "always", 8 | "args": { 9 | } 10 | } 11 | ], 12 | "effects": [ 13 | { 14 | "name": "copy_cgroup_setting", 15 | "args": { 16 | "from_setting": "./test033_from.cgroup", 17 | "to_setting": "./test033_to.cgroup", 18 | "dont_copy_if_zero": true, 19 | "validate": true 20 | } 21 | }, 22 | { 23 | "name": "cgroup_setting", 24 | "args": { 25 | "setting": "./test033_to.cgroup", 26 | "operator": "add", 27 | "value": "1024K", 28 | "validate": true 29 | } 30 | }, 31 | { 32 | "name": "cgroup_setting", 33 | "args": { 34 | "setting": "./test033_to.cgroup", 35 | "operator": "add", 36 | "value": "1g", 37 | "validate": true 38 | } 39 | }, 40 | { 41 | "name": "cgroup_setting", 42 | "args": { 43 | "setting": "./test033_to.cgroup", 44 | "operator": "add", 45 | "value": "1G", 46 | "validate": true 47 | } 48 | }, 49 | { 50 | "name": "cgroup_setting", 51 | "args": { 52 | "setting": "./test033_to.cgroup", 53 | "operator": "add", 54 | "value": "0T", 55 | "validate": true 56 | } 57 | }, 58 | { 59 | "name": "cgroup_setting", 60 | "args": { 61 | "setting": "./test033_to.cgroup", 62 | "operator": "subtract", 63 | "value": "512M", 64 | "validate": true 65 | } 66 | }, 67 | { 68 | "name": "cgroup_setting", 69 | "args": { 70 | "setting": "./test033_to.cgroup", 71 | "operator": "subtract", 72 | "value": "512m", 73 | "validate": true 74 | } 75 | } 76 | ] 77 | } 78 | ] 79 | } 80 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/034-cause-setting_ll_gt.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "long long setting > threshold", 5 | "causes": [ 6 | { 7 | "name": "setting", 8 | "args": { 9 | "setting": "034-cause-setting.setting", 10 | "threshold": 5, 11 | "operator": "greaterthan" 12 | } 13 | } 14 | ], 15 | "effects": [ 16 | { 17 | "name": "validate", 18 | "args": { 19 | "return_value": 65 20 | } 21 | } 22 | ] 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/035-cause-setting_ll_lt.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "long long setting < threshold", 5 | "causes": [ 6 | { 7 | "name": "setting", 8 | "args": { 9 | "setting": "035-cause-setting.setting", 10 | "threshold": 6000, 11 | "operator": "lessthan" 12 | } 13 | } 14 | ], 15 | "effects": [ 16 | { 17 | "name": "validate", 18 | "args": { 19 | "return_value": 66 20 | } 21 | } 22 | ] 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/036-cause-setting_float_gt.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "float setting > threshold", 5 | "causes": [ 6 | { 7 | "name": "setting", 8 | "args": { 9 | "setting": "036-cause-setting.setting", 10 | "threshold": 42.51, 11 | "operator": "greaterthan" 12 | } 13 | } 14 | ], 15 | "effects": [ 16 | { 17 | "name": "validate", 18 | "args": { 19 | "return_value": 67 20 | } 21 | } 22 | ] 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/037-cause-setting_float_lt.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "float setting < threshold", 5 | "causes": [ 6 | { 7 | "name": "setting", 8 | "args": { 9 | "setting": "037-cause-setting.setting", 10 | "threshold": 1.9945, 11 | "operator": "lessthan" 12 | } 13 | } 14 | ], 15 | "effects": [ 16 | { 17 | "name": "validate", 18 | "args": { 19 | "return_value": 68 20 | } 21 | } 22 | ] 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/038-cause-setting_ll_eq.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "long long setting == threshold", 5 | "causes": [ 6 | { 7 | "name": "setting", 8 | "args": { 9 | "setting": "038-cause-setting.setting", 10 | "threshold": 5, 11 | "operator": "equal" 12 | } 13 | } 14 | ], 15 | "effects": [ 16 | { 17 | "name": "validate", 18 | "args": { 19 | "return_value": 65 20 | } 21 | } 22 | ] 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/039-cause-setting_float_eq.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "float setting == threshold", 5 | "causes": [ 6 | { 7 | "name": "setting", 8 | "args": { 9 | "setting": "039-cause-setting.setting", 10 | "threshold": 1.995, 11 | "operator": "equal" 12 | } 13 | } 14 | ], 15 | "effects": [ 16 | { 17 | "name": "validate", 18 | "args": { 19 | "return_value": 68 20 | } 21 | } 22 | ] 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/040-cause-avg300_pressure_equal.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "pressure equal test.", 5 | "causes": [ 6 | { 7 | "name": "pressure", 8 | "args": { 9 | "pressure_file": "040-cause-avg300_pressure_equal.pressure", 10 | "threshold": 12.5, 11 | "duration": 3, 12 | "operator": "equal", 13 | "measurement": "some-avg300" 14 | } 15 | } 16 | ], 17 | "effects": [ 18 | { 19 | "name": "validate", 20 | "args": { 21 | "return_value": 42 22 | } 23 | } 24 | ] 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/041-cause-pressure_equal.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "pressure equal test.", 5 | "causes": [ 6 | { 7 | "name": "pressure", 8 | "args": { 9 | "pressure_file": "041-cause-pressure_equal.pressure", 10 | "threshold": 1234567890, 11 | "duration": 3, 12 | "operator": "equal", 13 | "measurement": "full-total" 14 | } 15 | } 16 | ], 17 | "effects": [ 18 | { 19 | "name": "validate", 20 | "args": { 21 | "return_value": 43 22 | } 23 | } 24 | ] 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/042-cause-periodic.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Periodically save off the contents of various files", 5 | "causes": [ 6 | { 7 | "name": "periodic", 8 | "description": "period is in milliseconds", 9 | "args": { 10 | "period": 1000 11 | } 12 | } 13 | ], 14 | "effects": [ 15 | { 16 | "name": "logger", 17 | "args": { 18 | "logfile": "mem.log", 19 | "separator_prefix": "<<<<< ", 20 | "date_format": "%Y-%m-%d-%H:%M:%S-%Z", 21 | "separator_postfix": " >>>>>", 22 | "utc": true, 23 | "file_separator": "==============================", 24 | "max_file_size": 128, 25 | "files": [ 26 | { 27 | "file": "test042_test_file1.txt" 28 | }, 29 | { 30 | "file": "test042_test_file2.txt" 31 | } 32 | ] 33 | } 34 | } 35 | ] 36 | } 37 | ] 38 | } 39 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/043-effect-logger-no-separators.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Periodically save off the contents of various files", 5 | "causes": [ 6 | { 7 | "name": "periodic", 8 | "description": "period is in milliseconds", 9 | "args": { 10 | "period": 1000 11 | } 12 | } 13 | ], 14 | "effects": [ 15 | { 16 | "name": "logger", 17 | "args": { 18 | "logfile": "mem.log", 19 | "max_file_size": 128, 20 | "files": [ 21 | { 22 | "file": "test043_test_file1.txt" 23 | }, 24 | { 25 | "file": "test043_test_file2.txt" 26 | } 27 | ] 28 | } 29 | } 30 | ] 31 | } 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/044-effect-logger-date-format.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Periodically save off the contents of various files", 5 | "causes": [ 6 | { 7 | "name": "periodic", 8 | "description": "period is in milliseconds", 9 | "args": { 10 | "period": 1000 11 | } 12 | } 13 | ], 14 | "effects": [ 15 | { 16 | "name": "logger", 17 | "args": { 18 | "logfile": "mem.log", 19 | "date_format": "%Y-%m-%d-%H:%M:%S-%Z", 20 | "utc": false, 21 | "max_file_size": 128, 22 | "files": [ 23 | { 24 | "file": "test044_test_file1.txt" 25 | }, 26 | { 27 | "file": "test044_test_file2.txt" 28 | } 29 | ] 30 | } 31 | } 32 | ] 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/045-effect-cgroup_memory_setting_add_int_max.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Add to an integer cgroup memory setting", 5 | "causes": [ 6 | { 7 | "name": "always", 8 | "args": { 9 | } 10 | } 11 | ], 12 | "effects": [ 13 | { 14 | "name": "cgroup_memory_setting", 15 | "args": { 16 | "setting": "./test045.cgroup", 17 | "value": "max", 18 | "operator": "set", 19 | "validate": true 20 | } 21 | }, 22 | { 23 | "name": "cgroup_memory_setting", 24 | "args": { 25 | "setting": "./test045.cgroup", 26 | "value": 5, 27 | "operator": "add", 28 | "validate": true 29 | } 30 | } 31 | ] 32 | } 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/045-effect-cgroup_memory_setting_set_add_int.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Add to an integer cgroup memory setting", 5 | "causes": [ 6 | { 7 | "name": "always", 8 | "args": { 9 | } 10 | } 11 | ], 12 | "effects": [ 13 | { 14 | "name": "cgroup_memory_setting", 15 | "args": { 16 | "setting": "./test045.cgroup", 17 | "value": 20, 18 | "operator": "set", 19 | "validate": true 20 | } 21 | }, 22 | { 23 | "name": "cgroup_memory_setting", 24 | "args": { 25 | "setting": "./test045.cgroup", 26 | "value": 5, 27 | "operator": "add", 28 | "validate": true 29 | } 30 | } 31 | ] 32 | } 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/046-effect-cgroup_memory_setting_sub_int_max.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Subtract from an integer cgroup memory setting", 5 | "causes": [ 6 | { 7 | "name": "always", 8 | "args": { 9 | } 10 | } 11 | ], 12 | "effects": [ 13 | { 14 | "name": "cgroup_memory_setting", 15 | "args": { 16 | "setting": "./test046.cgroup", 17 | "value": "max", 18 | "operator": "set", 19 | "validate": true 20 | } 21 | }, 22 | { 23 | "name": "cgroup_memory_setting", 24 | "args": { 25 | "setting": "./test046.cgroup", 26 | "value": 1024, 27 | "operator": "subtract", 28 | "validate": true 29 | } 30 | } 31 | ] 32 | } 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/047-effect-cgroup_memory_pre_set_add_int.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. 8 | * 9 | * This code is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * version 2 for more details (a copy is included in the LICENSE file that 13 | * accompanied this code). 14 | * 15 | * You should have received a copy of the GNU General Public License version 16 | * 2 along with this work; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 | * 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 | * or visit www.oracle.com if you need additional information or have any 21 | * questions. 22 | */ 23 | /** 24 | * Test to add to a cgroup integer setting 25 | * 26 | */ 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include 35 | 36 | #include "ftests.h" 37 | 38 | #define EXPECTED_RET -ETIME 39 | 40 | static const char * const cgroup_from_file = "./test047_from.cgroup"; 41 | static const char * const cgroup_file = "./test047.cgroup"; 42 | static const long long expected_value = 1235; 43 | 44 | int main(int argc, char *argv[]) 45 | { 46 | char config_path[FILENAME_MAX]; 47 | struct adaptived_ctx *ctx = NULL; 48 | struct sysinfo info; 49 | sysinfo(&info); 50 | int ret; 51 | 52 | snprintf(config_path, FILENAME_MAX - 1, "%s/047-effect-cgroup_memory_pre_set_add_int.json", argv[1]); 53 | config_path[FILENAME_MAX - 1] = '\0'; 54 | 55 | ctx = adaptived_init(config_path); 56 | if (!ctx) 57 | return AUTOMAKE_HARD_ERROR; 58 | 59 | write_file(cgroup_from_file, "1234"); 60 | write_file(cgroup_file, "max"); 61 | 62 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_MAX_LOOPS, 5); 63 | if (ret) 64 | goto err; 65 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_INTERVAL, 3000); 66 | if (ret) 67 | goto err; 68 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_SKIP_SLEEP, 1); 69 | if (ret) 70 | goto err; 71 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_LOG_LEVEL, LOG_DEBUG); 72 | if (ret) 73 | goto err; 74 | 75 | ret = adaptived_loop(ctx, true); 76 | if (ret != EXPECTED_RET) { 77 | adaptived_err("Test 047 returned: %d, expected: %d\n", ret, EXPECTED_RET); 78 | goto err; 79 | } 80 | 81 | ret = verify_int_file(cgroup_file, expected_value); 82 | if (ret) 83 | goto err; 84 | 85 | delete_file(cgroup_from_file); 86 | delete_file(cgroup_file); 87 | adaptived_release(&ctx); 88 | 89 | adaptived_dbg("cgroup memory pre_set_from test OK\n"); 90 | 91 | return AUTOMAKE_PASSED; 92 | 93 | err: 94 | delete_file(cgroup_from_file); 95 | delete_file(cgroup_file); 96 | adaptived_release(&ctx); 97 | 98 | return AUTOMAKE_HARD_ERROR; 99 | } 100 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/047-effect-cgroup_memory_pre_set_add_int.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Add to an integer cgroup memory setting after pre_set_from", 5 | "causes": [ 6 | { 7 | "name": "always", 8 | "args": { 9 | } 10 | } 11 | ], 12 | "effects": [ 13 | { 14 | "name": "cgroup_memory_setting", 15 | "args": { 16 | "pre_set_from": "./test047_from.cgroup", 17 | "setting": "./test047.cgroup", 18 | "value": 1, 19 | "operator": "add", 20 | "validate": true 21 | } 22 | } 23 | ] 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/048-cause-meminfo_gt.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "meminfo long long setting > threshold", 5 | "causes": [ 6 | { 7 | "name": "meminfo", 8 | "args": { 9 | "meminfo_file": "048-cause-meminfo_gt.setting", 10 | "field": "MemFree", 11 | "threshold": "493452944K", 12 | "operator": "greaterthan" 13 | } 14 | } 15 | ], 16 | "effects": [ 17 | { 18 | "name": "validate", 19 | "args": { 20 | "return_value": 65 21 | } 22 | } 23 | ] 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/049-cause-meminfo_lt.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "meminfo long long setting < threshold", 5 | "causes": [ 6 | { 7 | "name": "meminfo", 8 | "args": { 9 | "meminfo_file": "049-cause-meminfo_lt.setting", 10 | "field": "MemFree", 11 | "threshold": "493452943K", 12 | "operator": "lessthan" 13 | } 14 | } 15 | ], 16 | "effects": [ 17 | { 18 | "name": "validate", 19 | "args": { 20 | "return_value": 65 21 | } 22 | } 23 | ] 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/050-cause-meminfo_eq.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "meminfo long long setting = threshold", 5 | "causes": [ 6 | { 7 | "name": "meminfo", 8 | "args": { 9 | "meminfo_file": "050-cause-meminfo_eq.setting", 10 | "field": "MemFree", 11 | "threshold": 505295815680, 12 | "operator": "equal" 13 | } 14 | } 15 | ], 16 | "effects": [ 17 | { 18 | "name": "validate", 19 | "args": { 20 | "return_value": 65 21 | } 22 | } 23 | ] 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/051-cause-slabinfo_gt.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "slabinfo long long setting > threshold", 5 | "causes": [ 6 | { 7 | "name": "slabinfo", 8 | "args": { 9 | "slabinfo_file": "051-cause-slabinfo_gt.setting", 10 | "field": "kmalloc-32", 11 | "threshold": 172484, 12 | "operator": "greaterthan" 13 | } 14 | } 15 | ], 16 | "effects": [ 17 | { 18 | "name": "validate", 19 | "args": { 20 | "return_value": 65 21 | } 22 | } 23 | ] 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/052-cause-slabinfo_lt.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "slabinfo long long setting < threshold", 5 | "causes": [ 6 | { 7 | "name": "slabinfo", 8 | "args": { 9 | "slabinfo_file": "052-cause-slabinfo_lt.setting", 10 | "field": "kmalloc-32", 11 | "threshold": 172484, 12 | "operator": "lessthan" 13 | } 14 | } 15 | ], 16 | "effects": [ 17 | { 18 | "name": "validate", 19 | "args": { 20 | "return_value": 65 21 | } 22 | } 23 | ] 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/053-cause-slabinfo_eq.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "slabinfo long long setting = threshold", 5 | "causes": [ 6 | { 7 | "name": "slabinfo", 8 | "args": { 9 | "slabinfo_file": "053-cause-slabinfo_eq.setting", 10 | "field": "kmalloc-32", 11 | "column": "", 12 | "threshold": 172484, 13 | "operator": "equal" 14 | } 15 | } 16 | ], 17 | "effects": [ 18 | { 19 | "name": "validate", 20 | "args": { 21 | "return_value": 65 22 | } 23 | } 24 | ] 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/054-effect-print_schedstat.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Run the print_schedstat effect", 5 | "causes": [ 6 | { 7 | "name": "periodic", 8 | "description": "period is in milliseconds", 9 | "args": { 10 | "period": 1000 11 | } 12 | } 13 | ], 14 | "effects": [ 15 | { 16 | "name": "print_schedstat", 17 | "args": { 18 | "file": "stdout", 19 | "schedstat_file": "054-effect-print_schedstat.schedstat" 20 | } 21 | } 22 | ] 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/054-effect-print_schedstat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Copyright (c) 2024, Oracle and/or its affiliates. 3 | # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | # 5 | # This code is free software; you can redistribute it and/or modify it 6 | # under the terms of the GNU General Public License version 2 only, as 7 | # published by the Free Software Foundation. 8 | # 9 | # This code is distributed in the hope that it will be useful, but WITHOUT 10 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | # version 2 for more details (a copy is included in the LICENSE file that 13 | # accompanied this code). 14 | # 15 | # You should have received a copy of the GNU General Public License version 16 | # 2 along with this work; if not, write to the Free Software Foundation, 17 | # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 | # 19 | # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 | # or visit www.oracle.com if you need additional information or have any 21 | # questions. 22 | 23 | # 24 | # Test the print_schedstat effect 25 | # 26 | # 27 | 28 | import filecmp 29 | import adaptived 30 | import consts 31 | import ftests 32 | import sys 33 | import os 34 | 35 | CONFIG = '054-effect-print_schedstat.json' 36 | OUT_FILE = '054-effect-print_schedstat.out' 37 | EXPECTED_RET = 62 38 | MAX_LOOPS = 1 39 | 40 | def prereqs(config): 41 | result = consts.TEST_PASSED 42 | cause = None 43 | 44 | return result, cause 45 | 46 | 47 | def setup(config): 48 | pass 49 | 50 | 51 | def test(config): 52 | result = consts.TEST_PASSED 53 | cause = None 54 | 55 | out = adaptived.adaptived(config=CONFIG, max_loops=MAX_LOOPS, expected_ret=EXPECTED_RET) 56 | 57 | with open(OUT_FILE, 'w') as ofile: 58 | ofile.write(out) 59 | ofile.write('\n') 60 | 61 | match = filecmp.cmp(OUT_FILE, '054-effect-print_schedstat.expected', shallow=False) 62 | if not match: 63 | result = consts.TEST_FAILED 64 | cause = 'Expected out file differs from received out file' 65 | 66 | return result, cause 67 | 68 | 69 | def teardown(config): 70 | pass 71 | 72 | 73 | def main(config): 74 | [result, cause] = prereqs(config) 75 | if result != consts.TEST_PASSED: 76 | return [result, cause] 77 | 78 | try: 79 | setup(config) 80 | [result, cause] = test(config) 81 | finally: 82 | teardown(config) 83 | 84 | try: 85 | os.remove(OUT_FILE) 86 | except FileNotFoundError: 87 | pass 88 | 89 | return [result, cause] 90 | 91 | 92 | if __name__ == '__main__': 93 | config = ftests.parse_args() 94 | # this test was invoked directly. run only it 95 | config.args.num = int(os.path.basename(__file__).split('-')[0]) 96 | sys.exit(ftests.main(config)) 97 | 98 | # vim: set et ts=4 sw=4: 99 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/055-effect-setting_set_int.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. 8 | * 9 | * This code is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * version 2 for more details (a copy is included in the LICENSE file that 13 | * accompanied this code). 14 | * 15 | * You should have received a copy of the GNU General Public License version 16 | * 2 along with this work; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 | * 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 | * or visit www.oracle.com if you need additional information or have any 21 | * questions. 22 | */ 23 | /** 24 | * Test to set an integer setting 25 | * 26 | */ 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include 34 | 35 | #include "ftests.h" 36 | 37 | #define EXPECTED_RET -ETIME 38 | 39 | static const char * const setting_file = "./test055.setting"; 40 | static const int expected_value = 1133557799; 41 | 42 | int main(int argc, char *argv[]) 43 | { 44 | char config_path[FILENAME_MAX]; 45 | struct adaptived_ctx *ctx = NULL; 46 | int ret; 47 | 48 | snprintf(config_path, FILENAME_MAX - 1, "%s/055-effect-setting_set_int.json", argv[1]); 49 | config_path[FILENAME_MAX - 1] = '\0'; 50 | 51 | ctx = adaptived_init(config_path); 52 | if (!ctx) 53 | return AUTOMAKE_HARD_ERROR; 54 | 55 | write_file(setting_file, "13579"); 56 | 57 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_MAX_LOOPS, 1); 58 | if (ret) 59 | goto err; 60 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_INTERVAL, 3000); 61 | if (ret) 62 | goto err; 63 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_SKIP_SLEEP, 1); 64 | if (ret) 65 | goto err; 66 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_LOG_LEVEL, LOG_DEBUG); 67 | if (ret) 68 | goto err; 69 | 70 | ret = adaptived_loop(ctx, true); 71 | if (ret != EXPECTED_RET) 72 | goto err; 73 | 74 | ret = verify_int_file(setting_file, expected_value); 75 | if (ret) 76 | goto err; 77 | 78 | delete_file(setting_file); 79 | adaptived_release(&ctx); 80 | 81 | return AUTOMAKE_PASSED; 82 | 83 | err: 84 | delete_file(setting_file); 85 | adaptived_release(&ctx); 86 | 87 | return AUTOMAKE_HARD_ERROR; 88 | } 89 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/055-effect-setting_set_int.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Set an integer setting", 5 | "causes": [ 6 | { 7 | "name": "always", 8 | "args": { 9 | } 10 | } 11 | ], 12 | "effects": [ 13 | { 14 | "name": "setting", 15 | "args": { 16 | "setting": "./test055.setting", 17 | "value": 1133557799, 18 | "operator": "set", 19 | "validate": true 20 | } 21 | } 22 | ] 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/056-effect-setting_add_int.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. 8 | * 9 | * This code is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * version 2 for more details (a copy is included in the LICENSE file that 13 | * accompanied this code). 14 | * 15 | * You should have received a copy of the GNU General Public License version 16 | * 2 along with this work; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 | * 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 | * or visit www.oracle.com if you need additional information or have any 21 | * questions. 22 | */ 23 | /** 24 | * Test to add to an integer setting 25 | * 26 | */ 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include 34 | 35 | #include "ftests.h" 36 | 37 | #define EXPECTED_RET -ETIME 38 | 39 | static const char * const setting_file = "./test056.setting"; 40 | static const int expected_value = 1979; 41 | 42 | int main(int argc, char *argv[]) 43 | { 44 | char config_path[FILENAME_MAX]; 45 | struct adaptived_ctx *ctx = NULL; 46 | int ret; 47 | 48 | snprintf(config_path, FILENAME_MAX - 1, "%s/056-effect-setting_add_int.json", argv[1]); 49 | config_path[FILENAME_MAX - 1] = '\0'; 50 | 51 | ctx = adaptived_init(config_path); 52 | if (!ctx) 53 | return AUTOMAKE_HARD_ERROR; 54 | 55 | write_file(setting_file, "100"); 56 | 57 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_MAX_LOOPS, 1000); 58 | if (ret) 59 | goto err; 60 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_INTERVAL, 3000); 61 | if (ret) 62 | goto err; 63 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_SKIP_SLEEP, 1); 64 | if (ret) 65 | goto err; 66 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_LOG_LEVEL, LOG_INFO); 67 | if (ret) 68 | goto err; 69 | 70 | ret = adaptived_loop(ctx, true); 71 | if (ret != EXPECTED_RET) 72 | goto err; 73 | 74 | ret = verify_int_file(setting_file, expected_value); 75 | if (ret) 76 | goto err; 77 | 78 | delete_file(setting_file); 79 | adaptived_release(&ctx); 80 | 81 | return AUTOMAKE_PASSED; 82 | 83 | err: 84 | delete_file(setting_file); 85 | adaptived_release(&ctx); 86 | 87 | return AUTOMAKE_HARD_ERROR; 88 | } 89 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/056-effect-setting_add_int.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Add to an integer setting", 5 | "causes": [ 6 | { 7 | "name": "always", 8 | "args": { 9 | } 10 | } 11 | ], 12 | "effects": [ 13 | { 14 | "name": "setting", 15 | "args": { 16 | "setting": "./test056.setting", 17 | "value": 1000, 18 | "operator": "add", 19 | "limit": 1979, 20 | "validate": true 21 | } 22 | } 23 | ] 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/057-effect-setting_sub_int.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. 8 | * 9 | * This code is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * version 2 for more details (a copy is included in the LICENSE file that 13 | * accompanied this code). 14 | * 15 | * You should have received a copy of the GNU General Public License version 16 | * 2 along with this work; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 | * 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 | * or visit www.oracle.com if you need additional information or have any 21 | * questions. 22 | */ 23 | /** 24 | * Test to subtract from an integer setting 25 | * 26 | */ 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include 34 | 35 | #include "ftests.h" 36 | 37 | #define EXPECTED_RET -ETIME 38 | 39 | static const char * const setting_file = "./test057.setting"; 40 | static const int expected_value = 22222222; 41 | 42 | int main(int argc, char *argv[]) 43 | { 44 | char config_path[FILENAME_MAX]; 45 | struct adaptived_ctx *ctx = NULL; 46 | int ret; 47 | 48 | snprintf(config_path, FILENAME_MAX - 1, "%s/057-effect-setting_sub_int.json", argv[1]); 49 | config_path[FILENAME_MAX - 1] = '\0'; 50 | 51 | ctx = adaptived_init(config_path); 52 | if (!ctx) 53 | return AUTOMAKE_HARD_ERROR; 54 | 55 | write_file(setting_file, "44444444"); 56 | 57 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_MAX_LOOPS, 2000); 58 | if (ret) 59 | goto err; 60 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_INTERVAL, 6000); 61 | if (ret) 62 | goto err; 63 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_SKIP_SLEEP, 1); 64 | if (ret) 65 | goto err; 66 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_LOG_LEVEL, LOG_WARNING); 67 | if (ret) 68 | goto err; 69 | 70 | ret = adaptived_loop(ctx, true); 71 | if (ret != EXPECTED_RET) { 72 | adaptived_err("Test 057 returned: %d, expected: %d\n", ret, EXPECTED_RET); 73 | goto err; 74 | } 75 | 76 | ret = verify_int_file(setting_file, expected_value); 77 | if (ret) 78 | goto err; 79 | 80 | delete_file(setting_file); 81 | adaptived_release(&ctx); 82 | 83 | return AUTOMAKE_PASSED; 84 | 85 | err: 86 | delete_file(setting_file); 87 | adaptived_release(&ctx); 88 | 89 | return AUTOMAKE_HARD_ERROR; 90 | } 91 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/057-effect-setting_sub_int.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Subtract from an integer setting", 5 | "causes": [ 6 | { 7 | "name": "always", 8 | "args": { 9 | } 10 | } 11 | ], 12 | "effects": [ 13 | { 14 | "name": "setting", 15 | "args": { 16 | "setting": "./test057.setting", 17 | "value": 12345, 18 | "operator": "subtract", 19 | "limit": 22222222, 20 | "validate": true 21 | } 22 | } 23 | ] 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/058-cause-memorystat_gt.expected: -------------------------------------------------------------------------------- 1 | anon 9848233984 2 | file 9215131648 3 | kernel 1091489792 4 | kernel_stack 40566784 5 | pagetables 136364032 6 | sec_pagetables 0 7 | percpu 4979128 8 | sock 65536 9 | vmalloc 503808 10 | shmem 2357944320 11 | zswap 0 12 | zswapped 0 13 | file_mapped 1106423808 14 | file_dirty 2347008 15 | file_writeback 0 16 | swapcached 15605760 17 | anon_thp 0 18 | file_thp 6291456 19 | shmem_thp 954204160 20 | inactive_anon 737398784 21 | active_anon 10540683264 22 | inactive_file 5358653440 23 | active_file 1498562560 24 | unevictable 940503040 25 | slab_reclaimable 1048577 26 | slab_unreclaimable 110407136 27 | slab 905558872 28 | workingset_refault_anon 33493 29 | workingset_refault_file 337507 30 | workingset_activate_anon 27758 31 | workingset_activate_file 144565 32 | workingset_restore_anon 27758 33 | workingset_restore_file 144565 34 | workingset_nodereclaim 162818 35 | pgscan 8279640 36 | pgsteal 8038884 37 | pgscan_kswapd 7672689 38 | pgscan_direct 443242 39 | pgscan_khugepaged 163709 40 | pgsteal_kswapd 7442482 41 | pgsteal_direct 434108 42 | pgsteal_khugepaged 162294 43 | pgfault 8341266242 44 | pgmajfault 136574 45 | pgrefill 6825625 46 | pgactivate 90924 47 | pgdeactivate 0 48 | pglazyfree 0 49 | pglazyfreed 0 50 | zswpin 0 51 | zswpout 0 52 | zswpwb 0 53 | thp_fault_alloc 0 54 | thp_collapse_alloc 0 55 | thp_swpout 0 56 | thp_swpout_fallback 0 57 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/058-cause-memorystat_gt.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "memory.stat long long setting > threshold", 5 | "causes": [ 6 | { 7 | "name": "memory.stat", 8 | "args": { 9 | "stat_file": "058-memory.stat", 10 | "field": "slab_reclaimable", 11 | "threshold": "1M", 12 | "operator": "greaterthan" 13 | } 14 | } 15 | ], 16 | "effects": [ 17 | { 18 | "name": "validate", 19 | "args": { 20 | "return_value": 1234 21 | } 22 | } 23 | ] 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/058-cause-memorystat_gt.token: -------------------------------------------------------------------------------- 1 | anon 9848233984 2 | file 9215131648 3 | kernel 1091489792 4 | kernel_stack 40566784 5 | pagetables 136364032 6 | sec_pagetables 0 7 | percpu 4979128 8 | sock 65536 9 | vmalloc 503808 10 | shmem 2357944320 11 | zswap 0 12 | zswapped 0 13 | file_mapped 1106423808 14 | file_dirty 2347008 15 | file_writeback 0 16 | swapcached 15605760 17 | anon_thp 0 18 | file_thp 6291456 19 | shmem_thp 954204160 20 | inactive_anon 737398784 21 | active_anon 10540683264 22 | inactive_file 5358653440 23 | active_file 1498562560 24 | unevictable 940503040 25 | slab_reclaimable %lld 26 | slab_unreclaimable 110407136 27 | slab 905558872 28 | workingset_refault_anon 33493 29 | workingset_refault_file 337507 30 | workingset_activate_anon 27758 31 | workingset_activate_file 144565 32 | workingset_restore_anon 27758 33 | workingset_restore_file 144565 34 | workingset_nodereclaim 162818 35 | pgscan 8279640 36 | pgsteal 8038884 37 | pgscan_kswapd 7672689 38 | pgscan_direct 443242 39 | pgscan_khugepaged 163709 40 | pgsteal_kswapd 7442482 41 | pgsteal_direct 434108 42 | pgsteal_khugepaged 162294 43 | pgfault 8341266242 44 | pgmajfault 136574 45 | pgrefill 6825625 46 | pgactivate 90924 47 | pgdeactivate 0 48 | pglazyfree 0 49 | pglazyfreed 0 50 | zswpin 0 51 | zswpout 0 52 | zswpwb 0 53 | thp_fault_alloc 0 54 | thp_collapse_alloc 0 55 | thp_swpout 0 56 | thp_swpout_fallback 0 57 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/059-cause-memorystat_lt.expected: -------------------------------------------------------------------------------- 1 | anon 9848233984 2 | file 9215131648 3 | kernel 1091489792 4 | kernel_stack 40566784 5 | pagetables 136364032 6 | sec_pagetables 0 7 | percpu 4979128 8 | sock 65536 9 | vmalloc 503808 10 | shmem 2357944320 11 | zswap 0 12 | zswapped 0 13 | file_mapped 1106423808 14 | file_dirty 2347008 15 | file_writeback 0 16 | swapcached 15605760 17 | anon_thp 0 18 | file_thp 6291456 19 | shmem_thp 954204160 20 | inactive_anon 737398784 21 | active_anon 10540683264 22 | inactive_file 5358653440 23 | active_file 1498562560 24 | unevictable 940503040 25 | slab_reclaimable 834864792 26 | slab_unreclaimable 110407136 27 | slab 905558872 28 | workingset_refault_anon 33493 29 | workingset_refault_file 337507 30 | workingset_activate_anon 27758 31 | workingset_activate_file 144565 32 | workingset_restore_anon 27758 33 | workingset_restore_file 144565 34 | workingset_nodereclaim 10737418239 35 | pgscan 8279640 36 | pgsteal 8038884 37 | pgscan_kswapd 7672689 38 | pgscan_direct 443242 39 | pgscan_khugepaged 163709 40 | pgsteal_kswapd 7442482 41 | pgsteal_direct 434108 42 | pgsteal_khugepaged 162294 43 | pgfault 8341266242 44 | pgmajfault 136574 45 | pgrefill 6825625 46 | pgactivate 90924 47 | pgdeactivate 0 48 | pglazyfree 0 49 | pglazyfreed 0 50 | zswpin 0 51 | zswpout 0 52 | zswpwb 0 53 | thp_fault_alloc 0 54 | thp_collapse_alloc 0 55 | thp_swpout 0 56 | thp_swpout_fallback 0 57 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/059-cause-memorystat_lt.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "memory.stat long long setting < threshold", 5 | "causes": [ 6 | { 7 | "name": "memory.stat", 8 | "args": { 9 | "stat_file": "059-memory.stat", 10 | "field": "workingset_nodereclaim", 11 | "threshold": "10G", 12 | "operator": "lessthan" 13 | } 14 | } 15 | ], 16 | "effects": [ 17 | { 18 | "name": "validate", 19 | "args": { 20 | "return_value": 2345 21 | } 22 | } 23 | ] 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/059-cause-memorystat_lt.token: -------------------------------------------------------------------------------- 1 | anon 9848233984 2 | file 9215131648 3 | kernel 1091489792 4 | kernel_stack 40566784 5 | pagetables 136364032 6 | sec_pagetables 0 7 | percpu 4979128 8 | sock 65536 9 | vmalloc 503808 10 | shmem 2357944320 11 | zswap 0 12 | zswapped 0 13 | file_mapped 1106423808 14 | file_dirty 2347008 15 | file_writeback 0 16 | swapcached 15605760 17 | anon_thp 0 18 | file_thp 6291456 19 | shmem_thp 954204160 20 | inactive_anon 737398784 21 | active_anon 10540683264 22 | inactive_file 5358653440 23 | active_file 1498562560 24 | unevictable 940503040 25 | slab_reclaimable 834864792 26 | slab_unreclaimable 110407136 27 | slab 905558872 28 | workingset_refault_anon 33493 29 | workingset_refault_file 337507 30 | workingset_activate_anon 27758 31 | workingset_activate_file 144565 32 | workingset_restore_anon 27758 33 | workingset_restore_file 144565 34 | workingset_nodereclaim %lld 35 | pgscan 8279640 36 | pgsteal 8038884 37 | pgscan_kswapd 7672689 38 | pgscan_direct 443242 39 | pgscan_khugepaged 163709 40 | pgsteal_kswapd 7442482 41 | pgsteal_direct 434108 42 | pgsteal_khugepaged 162294 43 | pgfault 8341266242 44 | pgmajfault 136574 45 | pgrefill 6825625 46 | pgactivate 90924 47 | pgdeactivate 0 48 | pglazyfree 0 49 | pglazyfreed 0 50 | zswpin 0 51 | zswpout 0 52 | zswpwb 0 53 | thp_fault_alloc 0 54 | thp_collapse_alloc 0 55 | thp_swpout 0 56 | thp_swpout_fallback 0 57 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/060-cause-memorystat_eq.expected: -------------------------------------------------------------------------------- 1 | anon 9848233984 2 | file 9215131648 3 | kernel 1091489792 4 | kernel_stack 40566784 5 | pagetables 136364032 6 | sec_pagetables 0 7 | percpu 4979128 8 | sock 65536 9 | vmalloc 503808 10 | shmem 2357944320 11 | zswap 0 12 | zswapped 0 13 | file_mapped 1106423808 14 | file_dirty 2347008 15 | file_writeback 0 16 | swapcached 15605760 17 | anon_thp 0 18 | file_thp 6291456 19 | shmem_thp 954204160 20 | inactive_anon 737398784 21 | active_anon 10540683264 22 | inactive_file 5358653440 23 | active_file 1498562560 24 | unevictable 940503040 25 | slab_reclaimable 834864792 26 | slab_unreclaimable 110407136 27 | slab 905558872 28 | workingset_refault_anon 33493 29 | workingset_refault_file 337507 30 | workingset_activate_anon 27758 31 | workingset_activate_file 144565 32 | workingset_restore_anon 27758 33 | workingset_restore_file 144565 34 | workingset_nodereclaim 162818 35 | pgscan 8279640 36 | pgsteal 8038884 37 | pgscan_kswapd 7672689 38 | pgscan_direct 443242 39 | pgscan_khugepaged 163709 40 | pgsteal_kswapd 7442482 41 | pgsteal_direct 434108 42 | pgsteal_khugepaged 162294 43 | pgfault 8341266242 44 | pgmajfault 123456781 45 | pgrefill 6825625 46 | pgactivate 90924 47 | pgdeactivate 0 48 | pglazyfree 0 49 | pglazyfreed 0 50 | zswpin 0 51 | zswpout 0 52 | zswpwb 0 53 | thp_fault_alloc 0 54 | thp_collapse_alloc 0 55 | thp_swpout 0 56 | thp_swpout_fallback 0 57 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/060-cause-memorystat_eq.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "memory.stat long long setting == threshold", 5 | "causes": [ 6 | { 7 | "name": "memory.stat", 8 | "args": { 9 | "stat_file": "060-memory.stat", 10 | "field": "pgmajfault", 11 | "threshold": 123456781, 12 | "operator": "equal" 13 | } 14 | } 15 | ], 16 | "effects": [ 17 | { 18 | "name": "validate", 19 | "args": { 20 | "return_value": 3456 21 | } 22 | } 23 | ] 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/060-cause-memorystat_eq.token: -------------------------------------------------------------------------------- 1 | anon 9848233984 2 | file 9215131648 3 | kernel 1091489792 4 | kernel_stack 40566784 5 | pagetables 136364032 6 | sec_pagetables 0 7 | percpu 4979128 8 | sock 65536 9 | vmalloc 503808 10 | shmem 2357944320 11 | zswap 0 12 | zswapped 0 13 | file_mapped 1106423808 14 | file_dirty 2347008 15 | file_writeback 0 16 | swapcached 15605760 17 | anon_thp 0 18 | file_thp 6291456 19 | shmem_thp 954204160 20 | inactive_anon 737398784 21 | active_anon 10540683264 22 | inactive_file 5358653440 23 | active_file 1498562560 24 | unevictable 940503040 25 | slab_reclaimable 834864792 26 | slab_unreclaimable 110407136 27 | slab 905558872 28 | workingset_refault_anon 33493 29 | workingset_refault_file 337507 30 | workingset_activate_anon 27758 31 | workingset_activate_file 144565 32 | workingset_restore_anon 27758 33 | workingset_restore_file 144565 34 | workingset_nodereclaim 162818 35 | pgscan 8279640 36 | pgsteal 8038884 37 | pgscan_kswapd 7672689 38 | pgscan_direct 443242 39 | pgscan_khugepaged 163709 40 | pgsteal_kswapd 7442482 41 | pgsteal_direct 434108 42 | pgsteal_khugepaged 162294 43 | pgfault 8341266242 44 | pgmajfault %lld 45 | pgrefill 6825625 46 | pgactivate 90924 47 | pgdeactivate 0 48 | pglazyfree 0 49 | pglazyfreed 0 50 | zswpin 0 51 | zswpout 0 52 | zswpwb 0 53 | thp_fault_alloc 0 54 | thp_collapse_alloc 0 55 | thp_swpout 0 56 | thp_swpout_fallback 0 57 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/061-cause-top_cpu_gt.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "top cpu field setting > threshold", 5 | "causes": [ 6 | { 7 | "name": "top", 8 | "args": { 9 | "stat_file": "061-cause-top_cpu_gt.setting", 10 | "component": "cpu", 11 | "field": "user", 12 | "threshold": 99.2, 13 | "display": true, 14 | "operator": "greaterthan" 15 | } 16 | } 17 | ], 18 | "effects": [ 19 | { 20 | "name": "validate", 21 | "args": { 22 | "return_value": 65 23 | } 24 | } 25 | ] 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/062-cause-top_cpu_lt.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "top cpu field setting < threshold", 5 | "causes": [ 6 | { 7 | "name": "top", 8 | "args": { 9 | "stat_file": "062-cause-top_cpu_lt.setting", 10 | "component": "cpu", 11 | "field": "idle", 12 | "threshold": 91.0, 13 | "display": true, 14 | "operator": "lessthan" 15 | } 16 | } 17 | ], 18 | "effects": [ 19 | { 20 | "name": "validate", 21 | "args": { 22 | "return_value": 65 23 | } 24 | } 25 | ] 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/063-cause-top_mem_gt.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "top memory field setting > threshold", 5 | "causes": [ 6 | { 7 | "name": "top", 8 | "args": { 9 | "component": "mem", 10 | "meminfo_file": "063-cause-top_mem_gt.setting", 11 | "field": "free", 12 | "threshold": "493453005K", 13 | "display": true, 14 | "operator": "greaterthan" 15 | } 16 | } 17 | ], 18 | "effects": [ 19 | { 20 | "name": "validate", 21 | "args": { 22 | "return_value": 65 23 | } 24 | } 25 | ] 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/064-cause-top_mem_lt.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "top memory field setting < threshold", 5 | "causes": [ 6 | { 7 | "name": "top", 8 | "args": { 9 | "component": "mem", 10 | "meminfo_file": "064-cause-top_mem_lt.setting", 11 | "field": "total", 12 | "threshold": "527700340K", 13 | "display": true, 14 | "operator": "lessthan" 15 | } 16 | } 17 | ], 18 | "effects": [ 19 | { 20 | "name": "validate", 21 | "args": { 22 | "return_value": 65 23 | } 24 | } 25 | ] 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/065-daemon_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. 8 | * 9 | * This code is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * version 2 for more details (a copy is included in the LICENSE file that 13 | * accompanied this code). 14 | * 15 | * You should have received a copy of the GNU General Public License version 16 | * 2 along with this work; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 | * 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 | * or visit www.oracle.com if you need additional information or have any 21 | * questions. 22 | */ 23 | /** 24 | * daemon test 25 | * 26 | */ 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include 34 | 35 | #include "ftests.h" 36 | 37 | #define EXPECTED_RET -ETIME 38 | 39 | int main(int argc, char *argv[]) 40 | { 41 | struct adaptived_ctx *ctx = NULL; 42 | int ret; 43 | 44 | /* Run as as daemon. */ 45 | ctx = adaptived_init(NULL); 46 | if (!ctx) 47 | return AUTOMAKE_HARD_ERROR; 48 | 49 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_MAX_LOOPS, 2); 50 | if (ret) 51 | goto err; 52 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_INTERVAL, 1000); 53 | if (ret) 54 | goto err; 55 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_SKIP_SLEEP, 1); 56 | if (ret) 57 | goto err; 58 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_LOG_LEVEL, LOG_DEBUG); 59 | if (ret) 60 | goto err; 61 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_DAEMON_MODE, 1); 62 | if (ret) 63 | goto err; 64 | 65 | ret = adaptived_loop(ctx, false); 66 | if (ret != EXPECTED_RET) 67 | goto err; 68 | 69 | adaptived_release(&ctx); 70 | 71 | /* Do not run as daemon. */ 72 | ctx = adaptived_init(NULL); 73 | if (!ctx) 74 | return AUTOMAKE_HARD_ERROR; 75 | 76 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_MAX_LOOPS, 2); 77 | if (ret) 78 | goto err; 79 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_INTERVAL, 1000); 80 | if (ret) 81 | goto err; 82 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_SKIP_SLEEP, 1); 83 | if (ret) 84 | goto err; 85 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_LOG_LEVEL, LOG_DEBUG); 86 | if (ret) 87 | goto err; 88 | 89 | ret = adaptived_loop(ctx, false); 90 | if (ret != EXPECTED_RET) 91 | goto err; 92 | 93 | adaptived_release(&ctx); 94 | 95 | return AUTOMAKE_PASSED; 96 | 97 | err: 98 | adaptived_release(&ctx); 99 | 100 | return AUTOMAKE_HARD_ERROR; 101 | } 102 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/066-cause-cgroup_memory_setting_ll_lt.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Cgroup long long memory setting < threshold", 5 | "causes": [ 6 | { 7 | "name": "cgroup_memory_setting", 8 | "args": { 9 | "setting": "066-cause-cgroup_memory_setting.setting", 10 | "threshold": 6000, 11 | "operator": "lessthan" 12 | } 13 | } 14 | ], 15 | "effects": [ 16 | { 17 | "name": "validate", 18 | "args": { 19 | "return_value": 66 20 | } 21 | } 22 | ] 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/067-effect-kill_processes.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Kill up to 6 memory hogs", 5 | "causes": [ 6 | { 7 | "name": "meminfo", 8 | "args": { 9 | "meminfo_file": "067-effect-kill_processes.setting", 10 | "field": "MemFree", 11 | "threshold": "493452943K", 12 | "operator": "lessthan" 13 | } 14 | } 15 | ], 16 | "effects": [ 17 | { 18 | "name": "kill_processes", 19 | "args": { 20 | "proc_names": [ 21 | { "name": "067_process" }, 22 | { "name": "foo" } 23 | ], 24 | "count": 6, 25 | "field": "vsize" 26 | } 27 | } 28 | ] 29 | } 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/068-effect-kill_processes_rss.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Kill up to 2 memory hogs per loop", 5 | "causes": [ 6 | { 7 | "name": "always", 8 | "args": { 9 | } 10 | } 11 | ], 12 | "effects": [ 13 | { 14 | "name": "kill_processes", 15 | "args": { 16 | "proc_names": [ 17 | { "name": "068_process" } 18 | ], 19 | "count": 2, 20 | "field": "rss" 21 | } 22 | } 23 | ] 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/069-effect-signal.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Send a signal to some processes", 5 | "causes": [ 6 | { 7 | "name": "always", 8 | "args": { 9 | } 10 | } 11 | ], 12 | "effects": [ 13 | { 14 | "name": "signal", 15 | "args": { 16 | "proc_names": [ 17 | { "name": "069_process" }, 18 | { "name": "foo" } 19 | ], 20 | "signal": 2 21 | } 22 | } 23 | ] 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/070-rule-multiple_rules.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025, Oracle and/or its affiliates. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. 8 | * 9 | * This code is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * version 2 for more details (a copy is included in the LICENSE file that 13 | * accompanied this code). 14 | * 15 | * You should have received a copy of the GNU General Public License version 16 | * 2 along with this work; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 | * 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 | * or visit www.oracle.com if you need additional information or have any 21 | * questions. 22 | */ 23 | /** 24 | * Test to verify all rules are properly loaded 25 | * 26 | */ 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include 34 | 35 | #include "ftests.h" 36 | 37 | static void *adaptived_wrapper(void *arg) 38 | { 39 | struct adaptived_ctx *ctx = arg; 40 | uintptr_t ret; 41 | 42 | ret = adaptived_loop(ctx, true); 43 | 44 | return (void *)ret; 45 | } 46 | 47 | int main(int argc, char *argv[]) 48 | { 49 | char config_path[FILENAME_MAX]; 50 | pthread_t adaptived_thread; 51 | struct adaptived_ctx *ctx; 52 | uint32_t rule_cnt = 0; 53 | void *tret; 54 | int ret; 55 | 56 | snprintf(config_path, FILENAME_MAX - 1, "%s/070-rule-multiple_rules.json", argv[1]); 57 | config_path[FILENAME_MAX - 1] = '\0'; 58 | 59 | ctx = adaptived_init(config_path); 60 | if (!ctx) 61 | return AUTOMAKE_HARD_ERROR; 62 | 63 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_LOG_LEVEL, LOG_DEBUG); 64 | if (ret) 65 | goto err; 66 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_INTERVAL, 1500); 67 | if (ret) 68 | goto err; 69 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_MAX_LOOPS, 2); 70 | if (ret) 71 | goto err; 72 | 73 | ret = pthread_create(&adaptived_thread, NULL, &adaptived_wrapper, ctx); 74 | if (ret) 75 | goto err; 76 | 77 | /* wait for the adaptived loop to get up and running */ 78 | sleep(1); 79 | 80 | ret = adaptived_get_attr(ctx, ADAPTIVED_ATTR_RULE_CNT, &rule_cnt); 81 | if (ret) 82 | goto err; 83 | if (rule_cnt != 5) 84 | goto err; 85 | 86 | pthread_join(adaptived_thread, &tret); 87 | 88 | if (tret != (void *)-ETIME) 89 | goto err; 90 | 91 | adaptived_release(&ctx); 92 | 93 | return AUTOMAKE_PASSED; 94 | 95 | err: 96 | adaptived_release(&ctx); 97 | 98 | return AUTOMAKE_HARD_ERROR; 99 | } 100 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/070-rule-multiple_rules.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "1", 5 | "causes": [ 6 | { 7 | "name": "always", 8 | "args": { 9 | } 10 | } 11 | ], 12 | "effects": [ 13 | { 14 | "name": "print", 15 | "args": { 16 | "file": "stdout", 17 | "message": "Rule 1\n" 18 | } 19 | } 20 | ] 21 | }, 22 | { 23 | "name": "2", 24 | "causes": [ 25 | { 26 | "name": "always", 27 | "args": { 28 | } 29 | } 30 | ], 31 | "effects": [ 32 | { 33 | "name": "print", 34 | "args": { 35 | "file": "stdout", 36 | "message": "Rule 2\n" 37 | } 38 | } 39 | ] 40 | }, 41 | { 42 | "name": "3", 43 | "causes": [ 44 | { 45 | "name": "always", 46 | "args": { 47 | } 48 | } 49 | ], 50 | "effects": [ 51 | { 52 | "name": "print", 53 | "args": { 54 | "file": "stdout", 55 | "message": "Rule 3\n" 56 | } 57 | } 58 | ] 59 | }, 60 | { 61 | "name": "4", 62 | "causes": [ 63 | { 64 | "name": "always", 65 | "args": { 66 | } 67 | } 68 | ], 69 | "effects": [ 70 | { 71 | "name": "print", 72 | "args": { 73 | "file": "stdout", 74 | "message": "Rule 4\n" 75 | } 76 | } 77 | ] 78 | }, 79 | { 80 | "name": "5", 81 | "causes": [ 82 | { 83 | "name": "always", 84 | "args": { 85 | } 86 | } 87 | ], 88 | "effects": [ 89 | { 90 | "name": "print", 91 | "args": { 92 | "file": "stdout", 93 | "message": "Rule 5\n" 94 | } 95 | } 96 | ] 97 | } 98 | ] 99 | } 100 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/1000-sudo-effect-sd_bus_setting_set_int.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. 8 | * 9 | * This code is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * version 2 for more details (a copy is included in the LICENSE file that 13 | * accompanied this code). 14 | * 15 | * You should have received a copy of the GNU General Public License version 16 | * 2 along with this work; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 | * 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 | * or visit www.oracle.com if you need additional information or have any 21 | * questions. 22 | */ 23 | /** 24 | * Test to set a cgroup integer setting via sd_bus 25 | * 26 | */ 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #include 36 | 37 | #include "ftests.h" 38 | 39 | #define EXPECTED_RET -ETIME 40 | 41 | static const char * const cgroup_slice_name = "sudo1000.slice"; 42 | static const int expected_value = 89997312; /* Must be multiple of 4K */ 43 | 44 | int main(int argc, char *argv[]) 45 | { 46 | char *cgrp_path = NULL, *cgrp_file = NULL; 47 | char config_path[FILENAME_MAX]; 48 | struct adaptived_ctx *ctx = NULL; 49 | int ret, version; 50 | 51 | snprintf(config_path, FILENAME_MAX - 1, "%s/1000-sudo-effect-sd_bus_setting_set_int.json", argv[1]); 52 | config_path[FILENAME_MAX - 1] = '\0'; 53 | 54 | ctx = adaptived_init(config_path); 55 | if (!ctx) 56 | return AUTOMAKE_HARD_ERROR; 57 | 58 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_MAX_LOOPS, 1); 59 | if (ret) 60 | goto err; 61 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_INTERVAL, 3000); 62 | if (ret) 63 | goto err; 64 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_SKIP_SLEEP, 1); 65 | if (ret) 66 | goto err; 67 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_LOG_LEVEL, LOG_DEBUG); 68 | if (ret) 69 | goto err; 70 | 71 | ret = adaptived_loop(ctx, true); 72 | if (ret != EXPECTED_RET) 73 | goto err; 74 | 75 | ret = get_cgroup_version(&version); 76 | if (ret < 0) 77 | goto err; 78 | 79 | if (version == 1) 80 | ret = build_cgroup_path("memory", cgroup_slice_name, &cgrp_path); 81 | else if (version == 2) 82 | ret = build_cgroup_path(NULL, cgroup_slice_name, &cgrp_path); 83 | if (ret < 0) 84 | goto err; 85 | 86 | ret = build_systemd_memory_max_file(cgrp_path, &cgrp_file); 87 | if (ret < 0) 88 | goto err; 89 | 90 | ret = verify_int_file(cgrp_file, expected_value); 91 | if (ret) 92 | goto err; 93 | 94 | adaptived_release(&ctx); 95 | stop_transient(cgroup_slice_name); 96 | if (cgrp_file) 97 | free(cgrp_file); 98 | if (cgrp_path) 99 | free(cgrp_path); 100 | 101 | return AUTOMAKE_PASSED; 102 | 103 | err: 104 | adaptived_release(&ctx); 105 | stop_transient(cgroup_slice_name); 106 | if (cgrp_file) 107 | free(cgrp_file); 108 | if (cgrp_path) 109 | free(cgrp_path); 110 | 111 | return AUTOMAKE_HARD_ERROR; 112 | } 113 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/1000-sudo-effect-sd_bus_setting_set_int.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Set an integer cgroup setting via sd_bus", 5 | "causes": [ 6 | { 7 | "name": "always", 8 | "args": { 9 | } 10 | } 11 | ], 12 | "effects": [ 13 | { 14 | "name": "sd_bus_setting", 15 | "args": { 16 | "target": "sudo1000.slice", 17 | "setting": "MemoryMax", 18 | "value": 89997312, 19 | "operator": "set", 20 | "validate": true, 21 | "runtime": true 22 | } 23 | } 24 | ] 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/1001-sudo-effect-sd_bus_setting_add_int.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. 8 | * 9 | * This code is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * version 2 for more details (a copy is included in the LICENSE file that 13 | * accompanied this code). 14 | * 15 | * You should have received a copy of the GNU General Public License version 16 | * 2 along with this work; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 | * 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 | * or visit www.oracle.com if you need additional information or have any 21 | * questions. 22 | */ 23 | /** 24 | * Test to add to a cgroup integer setting via sd_bus 25 | * 26 | */ 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #include 36 | 37 | #include "ftests.h" 38 | 39 | #define EXPECTED_RET -ETIME 40 | 41 | static const char * const cgroup_slice_name = "sudo1001.slice"; 42 | static const int expected_value = 90001408; /* Must be multiple of 4K */ 43 | 44 | int main(int argc, char *argv[]) 45 | { 46 | char *cgrp_path = NULL, *cgrp_file = NULL; 47 | char config_path[FILENAME_MAX]; 48 | struct adaptived_ctx *ctx = NULL; 49 | int ret, version; 50 | 51 | snprintf(config_path, FILENAME_MAX - 1, "%s/1001-sudo-effect-sd_bus_setting_add_int.json", argv[1]); 52 | config_path[FILENAME_MAX - 1] = '\0'; 53 | 54 | ctx = adaptived_init(config_path); 55 | if (!ctx) 56 | return AUTOMAKE_HARD_ERROR; 57 | 58 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_MAX_LOOPS, 1); 59 | if (ret) 60 | goto err; 61 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_INTERVAL, 3000); 62 | if (ret) 63 | goto err; 64 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_SKIP_SLEEP, 1); 65 | if (ret) 66 | goto err; 67 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_LOG_LEVEL, LOG_DEBUG); 68 | if (ret) 69 | goto err; 70 | 71 | ret = adaptived_loop(ctx, true); 72 | if (ret != EXPECTED_RET) 73 | goto err; 74 | 75 | ret = get_cgroup_version(&version); 76 | if (ret < 0) 77 | goto err; 78 | 79 | if (version == 1) 80 | ret = build_cgroup_path("memory", cgroup_slice_name, &cgrp_path); 81 | else if (version == 2) 82 | ret = build_cgroup_path(NULL, cgroup_slice_name, &cgrp_path); 83 | if (ret < 0) 84 | goto err; 85 | 86 | ret = build_systemd_memory_max_file(cgrp_path, &cgrp_file); 87 | if (ret < 0) 88 | goto err; 89 | 90 | ret = verify_int_file(cgrp_file, expected_value); 91 | if (ret) 92 | goto err; 93 | 94 | adaptived_release(&ctx); 95 | stop_transient(cgroup_slice_name); 96 | if (cgrp_file) 97 | free(cgrp_file); 98 | if (cgrp_path) 99 | free(cgrp_path); 100 | 101 | return AUTOMAKE_PASSED; 102 | 103 | err: 104 | adaptived_release(&ctx); 105 | stop_transient(cgroup_slice_name); 106 | if (cgrp_file) 107 | free(cgrp_file); 108 | if (cgrp_path) 109 | free(cgrp_path); 110 | 111 | return AUTOMAKE_HARD_ERROR; 112 | } 113 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/1001-sudo-effect-sd_bus_setting_add_int.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Add to an integer cgroup setting via sd_bus", 5 | "causes": [ 6 | { 7 | "name": "always", 8 | "args": { 9 | } 10 | } 11 | ], 12 | "effects": [ 13 | { 14 | "name": "sd_bus_setting", 15 | "args": { 16 | "target": "sudo1001.slice", 17 | "setting": "MemoryMax", 18 | "value": 89997312, 19 | "operator": "set", 20 | "runtime": true 21 | } 22 | }, 23 | { 24 | "name": "sd_bus_setting", 25 | "args": { 26 | "target": "sudo1001.slice", 27 | "setting": "MemoryMax", 28 | "value": 4096, 29 | "operator": "add", 30 | "validate": true, 31 | "runtime": true 32 | } 33 | } 34 | ] 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/1002-sudo-effect-sd_bus_setting_sub_int.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. 8 | * 9 | * This code is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * version 2 for more details (a copy is included in the LICENSE file that 13 | * accompanied this code). 14 | * 15 | * You should have received a copy of the GNU General Public License version 16 | * 2 along with this work; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 | * 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 | * or visit www.oracle.com if you need additional information or have any 21 | * questions. 22 | */ 23 | /** 24 | * Test to subtract to a cgroup integer setting via sd_bus 25 | * 26 | */ 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #include 36 | 37 | #include "ftests.h" 38 | 39 | #define EXPECTED_RET -ETIME 40 | 41 | static const char * const cgroup_slice_name = "sudo1002.slice"; 42 | static const int expected_value = 89993216; /* Must be multiple of 4K */ 43 | 44 | int main(int argc, char *argv[]) 45 | { 46 | char *cgrp_path = NULL, *cgrp_file = NULL; 47 | char config_path[FILENAME_MAX]; 48 | struct adaptived_ctx *ctx = NULL; 49 | int ret, version; 50 | 51 | snprintf(config_path, FILENAME_MAX - 1, "%s/1002-sudo-effect-sd_bus_setting_sub_int.json", argv[1]); 52 | config_path[FILENAME_MAX - 1] = '\0'; 53 | 54 | ctx = adaptived_init(config_path); 55 | if (!ctx) 56 | return AUTOMAKE_HARD_ERROR; 57 | 58 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_MAX_LOOPS, 1); 59 | if (ret) 60 | goto err; 61 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_INTERVAL, 3000); 62 | if (ret) 63 | goto err; 64 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_SKIP_SLEEP, 1); 65 | if (ret) 66 | goto err; 67 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_LOG_LEVEL, LOG_DEBUG); 68 | if (ret) 69 | goto err; 70 | 71 | ret = adaptived_loop(ctx, true); 72 | if (ret != EXPECTED_RET) 73 | goto err; 74 | 75 | ret = get_cgroup_version(&version); 76 | if (ret < 0) 77 | goto err; 78 | 79 | if (version == 1) 80 | ret = build_cgroup_path("memory", cgroup_slice_name, &cgrp_path); 81 | else if (version == 2) 82 | ret = build_cgroup_path(NULL, cgroup_slice_name, &cgrp_path); 83 | if (ret < 0) 84 | goto err; 85 | 86 | ret = build_systemd_memory_max_file(cgrp_path, &cgrp_file); 87 | if (ret < 0) 88 | goto err; 89 | 90 | ret = verify_int_file(cgrp_file, expected_value); 91 | if (ret) 92 | goto err; 93 | 94 | adaptived_release(&ctx); 95 | stop_transient(cgroup_slice_name); 96 | if (cgrp_file) 97 | free(cgrp_file); 98 | if (cgrp_path) 99 | free(cgrp_path); 100 | 101 | return AUTOMAKE_PASSED; 102 | 103 | err: 104 | adaptived_release(&ctx); 105 | stop_transient(cgroup_slice_name); 106 | if (cgrp_file) 107 | free(cgrp_file); 108 | if (cgrp_path) 109 | free(cgrp_path); 110 | 111 | return AUTOMAKE_HARD_ERROR; 112 | } 113 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/1002-sudo-effect-sd_bus_setting_sub_int.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Subtract an integer from a cgroup setting via sd_bus", 5 | "causes": [ 6 | { 7 | "name": "always", 8 | "args": { 9 | } 10 | } 11 | ], 12 | "effects": [ 13 | { 14 | "name": "sd_bus_setting", 15 | "args": { 16 | "target": "sudo1002.slice", 17 | "setting": "MemoryMax", 18 | "value": 89997312, 19 | "operator": "set", 20 | "runtime": true 21 | } 22 | }, 23 | { 24 | "name": "sd_bus_setting", 25 | "args": { 26 | "target": "sudo1002.slice", 27 | "setting": "MemoryMax", 28 | "value": 4096, 29 | "operator": "subtract", 30 | "validate": true, 31 | "runtime": true 32 | } 33 | } 34 | ] 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/1003-sudo-effect-sd_bus_setting-CPUQuota.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Set CPUQuota & CPUQuotaPeriodSec via sd_bus", 5 | "causes": [ 6 | { 7 | "name": "always", 8 | "args": { 9 | } 10 | } 11 | ], 12 | "effects": [ 13 | { 14 | "name": "sd_bus_setting", 15 | "args": { 16 | "target": "sudo1003.slice", 17 | "setting": "CPUQuotaPeriodSec", 18 | "value": "1s", 19 | "operator": "set", 20 | "runtime": true 21 | } 22 | }, 23 | { 24 | "name": "sd_bus_setting", 25 | "args": { 26 | "target": "sudo1003.slice", 27 | "setting": "CPUQuota", 28 | "value": "44%", 29 | "operator": "set", 30 | "runtime": true 31 | } 32 | } 33 | ] 34 | } 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/1004-sudo-effect-sd_bus_setting_add_int_infinity.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Attempt to add an integer to a cgroup setting at infinity via sd_bus", 5 | "causes": [ 6 | { 7 | "name": "always", 8 | "args": { 9 | } 10 | } 11 | ], 12 | "effects": [ 13 | { 14 | "name": "sd_bus_setting", 15 | "args": { 16 | "target": "sudo1004.slice", 17 | "setting": "MemoryMax", 18 | "value": "infinity", 19 | "operator": "set", 20 | "validate": true, 21 | "runtime": true 22 | } 23 | }, 24 | { 25 | "name": "sd_bus_setting", 26 | "args": { 27 | "target": "sudo1004.slice", 28 | "setting": "MemoryMax", 29 | "value": 4096, 30 | "operator": "add", 31 | "validate": true, 32 | "runtime": true 33 | } 34 | } 35 | ] 36 | } 37 | ] 38 | } 39 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/1005-sudo-effect-sd_bus_setting_sub_infinity.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Subtract an integer from cgroup setting at infinity via sd_bus", 5 | "causes": [ 6 | { 7 | "name": "always", 8 | "args": { 9 | } 10 | } 11 | ], 12 | "effects": [ 13 | { 14 | "name": "sd_bus_setting", 15 | "args": { 16 | "target": "sudo1005.slice", 17 | "setting": "MemoryMax", 18 | "value": "infinity", 19 | "operator": "set", 20 | "validate": true, 21 | "runtime": true 22 | } 23 | }, 24 | { 25 | "name": "sd_bus_setting", 26 | "args": { 27 | "target": "sudo1005.slice", 28 | "setting": "MemoryMax", 29 | "value": 4096, 30 | "operator": "subtract", 31 | "validate": true, 32 | "runtime": true 33 | } 34 | } 35 | ] 36 | } 37 | ] 38 | } 39 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/1006-sudo-effect-sd_bus_setting_set_int_scope.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Set an integer cgroup setting in a scope via sd_bus", 5 | "causes": [ 6 | { 7 | "name": "always", 8 | "args": { 9 | } 10 | } 11 | ], 12 | "effects": [ 13 | { 14 | "name": "sd_bus_setting", 15 | "args": { 16 | "target": "sudo1006.scope", 17 | "setting": "MemoryMax", 18 | "value": 89997312, 19 | "operator": "set", 20 | "validate": true, 21 | "runtime": true 22 | } 23 | } 24 | ] 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/1007-sudo-effect-sd_bus_setting_set_str.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. 8 | * 9 | * This code is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * version 2 for more details (a copy is included in the LICENSE file that 13 | * accompanied this code). 14 | * 15 | * You should have received a copy of the GNU General Public License version 16 | * 2 along with this work; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 | * 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 | * or visit www.oracle.com if you need additional information or have any 21 | * questions. 22 | */ 23 | /** 24 | * Test to set a string property via sd_bus and validate it 25 | * 26 | * Note: this test relies on the validate config option to verify 27 | * the setting. 28 | * 29 | */ 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | #include 39 | 40 | #include "ftests.h" 41 | 42 | #define EXPECTED_RET -ETIME 43 | 44 | static const char * const cgroup_slice_name = "sudo1007.slice"; 45 | 46 | int main(int argc, char *argv[]) 47 | { 48 | char config_path[FILENAME_MAX]; 49 | struct adaptived_ctx *ctx = NULL; 50 | int ret; 51 | 52 | snprintf(config_path, FILENAME_MAX - 1, "%s/1007-sudo-effect-sd_bus_setting_set_str.json", argv[1]); 53 | config_path[FILENAME_MAX - 1] = '\0'; 54 | 55 | ctx = adaptived_init(config_path); 56 | if (!ctx) 57 | return AUTOMAKE_HARD_ERROR; 58 | 59 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_MAX_LOOPS, 1); 60 | if (ret) 61 | goto err; 62 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_INTERVAL, 3000); 63 | if (ret) 64 | goto err; 65 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_SKIP_SLEEP, 1); 66 | if (ret) 67 | goto err; 68 | ret = adaptived_set_attr(ctx, ADAPTIVED_ATTR_LOG_LEVEL, LOG_DEBUG); 69 | if (ret) 70 | goto err; 71 | 72 | ret = adaptived_loop(ctx, true); 73 | if (ret != EXPECTED_RET) 74 | goto err; 75 | 76 | adaptived_release(&ctx); 77 | stop_transient(cgroup_slice_name); 78 | 79 | return AUTOMAKE_PASSED; 80 | 81 | err: 82 | adaptived_release(&ctx); 83 | stop_transient(cgroup_slice_name); 84 | 85 | return AUTOMAKE_HARD_ERROR; 86 | } 87 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/1007-sudo-effect-sd_bus_setting_set_str.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": [ 3 | { 4 | "name": "Set a string property via sd_bus", 5 | "causes": [ 6 | { 7 | "name": "always", 8 | "args": { 9 | } 10 | } 11 | ], 12 | "effects": [ 13 | { 14 | "name": "sd_bus_setting", 15 | "args": { 16 | "target": "sudo1007.slice", 17 | "setting": "DevicePolicy", 18 | "value": "closed", 19 | "operator": "set", 20 | "validate": true, 21 | "runtime": true 22 | } 23 | } 24 | ] 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/adaptived.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Copyright (c) 2024, Oracle and/or its affiliates. 3 | # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | # 5 | # This code is free software; you can redistribute it and/or modify it 6 | # under the terms of the GNU General Public License version 2 only, as 7 | # published by the Free Software Foundation. 8 | # 9 | # This code is distributed in the hope that it will be useful, but WITHOUT 10 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | # version 2 for more details (a copy is included in the LICENSE file that 13 | # accompanied this code). 14 | # 15 | # You should have received a copy of the GNU General Public License version 16 | # 2 along with this work; if not, write to the Free Software Foundation, 17 | # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 | # 19 | # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 | # or visit www.oracle.com if you need additional information or have any 21 | # questions. 22 | 23 | # 24 | # Interface into the adaptived daemon for the adaptived functional tests 25 | # 26 | # 27 | 28 | from run import Run, RunError 29 | import consts 30 | import utils 31 | import os 32 | 33 | 34 | def adaptived(config=None, bhelp=False, interval=None, log_location=None, 35 | log_level=None, max_loops=None, expected_ret=None): 36 | """run the adaptived daemon 37 | """ 38 | cmd = list() 39 | out = None 40 | 41 | cmd.append(os.path.join(consts.ADAPTIVED_MOUNT_POINT, 'src/adaptived')) 42 | 43 | if config: 44 | tmp_config = config 45 | token = config.find('.token') 46 | if token > 0: 47 | tmp_config = config[:token] 48 | utils.config_find_and_replace(config, tmp_config) 49 | 50 | cmd.append('-c') 51 | cmd.append(tmp_config) 52 | 53 | if bhelp: 54 | cmd.append('-h') 55 | 56 | if interval: 57 | cmd.append('-i') 58 | cmd.append(str(interval)) 59 | 60 | if log_location: 61 | cmd.append('-L') 62 | cmd.append(log_location) 63 | 64 | if log_level: 65 | cmd.append('-l') 66 | cmd.append(str(log_level)) 67 | 68 | if max_loops: 69 | cmd.append('-m') 70 | cmd.append(str(max_loops)) 71 | 72 | try: 73 | out = Run.run(cmd) 74 | except RunError as re: 75 | if re.ret == expected_ret: 76 | out = re.stdout 77 | else: 78 | raise re 79 | finally: 80 | if tmp_config != config: 81 | os.remove(tmp_config) 82 | 83 | return out 84 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/config.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024, Oracle and/or its affiliates. 2 | # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 | # 4 | # This code is free software; you can redistribute it and/or modify it 5 | # under the terms of the GNU General Public License version 2 only, as 6 | # published by the Free Software Foundation. 7 | # 8 | # This code is distributed in the hope that it will be useful, but WITHOUT 9 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11 | # version 2 for more details (a copy is included in the LICENSE file that 12 | # accompanied this code). 13 | # 14 | # You should have received a copy of the GNU General Public License version 15 | # 2 along with this work; if not, write to the Free Software Foundation, 16 | # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 17 | # 18 | # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 19 | # or visit www.oracle.com if you need additional information or have any 20 | # questions. 21 | 22 | # 23 | # Config class for the adaptived functional tests 24 | # 25 | # 26 | 27 | import consts 28 | import utils 29 | import os 30 | 31 | 32 | class Config(object): 33 | def __init__(self, args): 34 | self.args = args 35 | self.skip_list = [] 36 | 37 | self.ftest_dir = os.path.dirname(os.path.abspath(__file__)) 38 | self.adaptived_dir = os.path.dirname(self.ftest_dir) 39 | 40 | self.test_suite = consts.TESTS_RUN_ALL_SUITES 41 | self.test_num = consts.TESTS_RUN_ALL 42 | self.verbose = False 43 | 44 | def __str__(self): 45 | out_str = 'Configuration\n' 46 | out_str += utils.indent('args = {}'.format(self.args), 4) 47 | out_str += utils.indent('skip_list = {}'.format(self.skip_list.join(',')), 4) 48 | 49 | return out_str 50 | 51 | 52 | class ConfigError(Exception): 53 | def __init__(self, message): 54 | super(ConfigError, self).__init__(message) 55 | 56 | def __str__(self): 57 | out_str = 'ConfigError:\n\tmessage = {}'.format(self.message) 58 | return out_str 59 | 60 | # vim: set et ts=4 sw=4: 61 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/consts.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024, Oracle and/or its affiliates. 2 | # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 | # 4 | # This code is free software; you can redistribute it and/or modify it 5 | # under the terms of the GNU General Public License version 2 only, as 6 | # published by the Free Software Foundation. 7 | # 8 | # This code is distributed in the hope that it will be useful, but WITHOUT 9 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11 | # version 2 for more details (a copy is included in the LICENSE file that 12 | # accompanied this code). 13 | # 14 | # You should have received a copy of the GNU General Public License version 15 | # 2 along with this work; if not, write to the Free Software Foundation, 16 | # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 17 | # 18 | # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 19 | # or visit www.oracle.com if you need additional information or have any 20 | # questions. 21 | 22 | # 23 | # Constants for the libcgroup functional tests 24 | # 25 | # Note: based on libcgroup's ftests.py 26 | # 27 | # 28 | 29 | import os 30 | 31 | DEFAULT_LOG_FILE = 'adaptived-ftests.log' 32 | 33 | LOG_CRITICAL = 1 34 | LOG_WARNING = 5 35 | LOG_DEBUG = 8 36 | DEFAULT_LOG_LEVEL = 5 37 | 38 | tests_dir = os.path.dirname(os.path.abspath(__file__)) 39 | ADAPTIVED_MOUNT_POINT = os.path.dirname(os.path.dirname(tests_dir)) 40 | 41 | TESTS_RUN_ALL = -1 42 | TESTS_RUN_ALL_SUITES = 'allsuites' 43 | TEST_PASSED = 'passed' 44 | TEST_FAILED = 'failed' 45 | TEST_SKIPPED = 'skipped' 46 | 47 | # vim: set et ts=4 sw=4: 48 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/ftests-c-wrapper.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright (c) 2024, Oracle and/or its affiliates. 3 | # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | # 5 | # This code is free software; you can redistribute it and/or modify it 6 | # under the terms of the GNU General Public License version 2 only, as 7 | # published by the Free Software Foundation. 8 | # 9 | # This code is distributed in the hope that it will be useful, but WITHOUT 10 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | # version 2 for more details (a copy is included in the LICENSE file that 13 | # accompanied this code). 14 | # 15 | # You should have received a copy of the GNU General Public License version 16 | # 2 along with this work; if not, write to the Free Software Foundation, 17 | # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 | # 19 | # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 | # or visit www.oracle.com if you need additional information or have any 21 | # questions. 22 | 23 | 24 | BASEDIR=$(dirname $0) 25 | 26 | FAILED_TESTS=() 27 | RET=0 28 | 29 | # Sort the files in reverse order so that the sudo tests are run last. They 30 | # can mess up the permissions on the code coverage files. 31 | FILES=$(ls | sort -r) 32 | 33 | for FILE in $FILES; do 34 | CMD="" 35 | if [[ $FILE =~ ^test[0-9]{3} ]]; then 36 | EXE=$FILE 37 | 38 | if [[ -x "./$EXE" ]]; then 39 | CMD="./$EXE" 40 | else 41 | CMD=${srcdir}/$EXE 42 | fi 43 | elif [[ $FILE =~ ^sudo1[0-9]{3} ]]; then 44 | EXE=$FILE 45 | 46 | if [[ -x "./$EXE" ]]; then 47 | CMD="sudo ./$EXE" 48 | else 49 | CMD=sudo ${srcdir}/$EXE 50 | fi 51 | fi 52 | if [ -z "$CMD" ] ; then 53 | echo "Missing command for $FILE." 54 | continue 55 | fi 56 | 57 | echo "Running $CMD $BASEDIR" 58 | $CMD $BASEDIR 59 | TMP_RET=$? 60 | echo "$CMD returned $TMP_RET" 61 | 62 | if [[ $TMP_RET -gt 0 ]]; then 63 | FAILED_TESTS+=($FILE) 64 | fi 65 | if [[ $TMP_RET -gt $RET ]]; then 66 | RET=$TMP_RET 67 | fi 68 | done 69 | 70 | if [[ ${#FAILED_TESTS[@]} > 0 ]]; then 71 | echo -e "\nThe following tests did not pass:" 72 | echo "---------------------------------" 73 | for FAILED_TEST in "${FAILED_TESTS[@]}"; do 74 | echo "$FAILED_TEST" 75 | done 76 | fi 77 | 78 | exit $RET 79 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/ftests-wrapper.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright (c) 2024, Oracle and/or its affiliates. 3 | # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | # 5 | # This code is free software; you can redistribute it and/or modify it 6 | # under the terms of the GNU General Public License version 2 only, as 7 | # published by the Free Software Foundation. 8 | # 9 | # This code is distributed in the hope that it will be useful, but WITHOUT 10 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | # version 2 for more details (a copy is included in the LICENSE file that 13 | # accompanied this code). 14 | # 15 | # You should have received a copy of the GNU General Public License version 16 | # 2 along with this work; if not, write to the Free Software Foundation, 17 | # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 | # 19 | # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 | # or visit www.oracle.com if you need additional information or have any 21 | # questions. 22 | 23 | # 24 | # Note: based on libcgroup's ftests-wrapper.sh 25 | # 26 | 27 | AUTOMAKE_SKIPPED=77 28 | AUTOMAKE_HARD_ERROR=99 29 | 30 | START_DIR=$PWD 31 | SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) 32 | 33 | if [ "$START_DIR" != "$SCRIPT_DIR" ]; then 34 | cp "$SCRIPT_DIR"/*.py "$START_DIR" 35 | cp "$SCRIPT_DIR"/*.json "$START_DIR" 36 | cp "$SCRIPT_DIR"/*.token "$START_DIR" 37 | cp "$SCRIPT_DIR"/*.schedstat "$START_DIR" 38 | cp "$SCRIPT_DIR"/*.expected "$START_DIR" 39 | fi 40 | 41 | 42 | ./ftests.py -l 10 -L "$START_DIR/ftests.py.log" 43 | RET=$? 44 | 45 | if [ -z "$srcdir" ]; then 46 | # $srcdir is set by automake but will likely be empty when run by hand and 47 | # that's fine 48 | srcdir="" 49 | else 50 | srcdir=$srcdir"/" 51 | fi 52 | 53 | if [ "$START_DIR" != "$SCRIPT_DIR" ]; then 54 | rm -f "$START_DIR"/*.py 55 | rm -f "$START_DIR"/*.json 56 | rm -f "$START_DIR"/*.token 57 | rm -f "$START_DIR"/*.schedstat 58 | rm -f "$START_DIR"/*.expected 59 | rm -fr "$START_DIR"/__pycache__ 60 | rm -f ftests.py.log 61 | fi 62 | 63 | exit $RET 64 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/log.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024, Oracle and/or its affiliates. 2 | # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 | # 4 | # This code is free software; you can redistribute it and/or modify it 5 | # under the terms of the GNU General Public License version 2 only, as 6 | # published by the Free Software Foundation. 7 | # 8 | # This code is distributed in the hope that it will be useful, but WITHOUT 9 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11 | # version 2 for more details (a copy is included in the LICENSE file that 12 | # accompanied this code). 13 | # 14 | # You should have received a copy of the GNU General Public License version 15 | # 2 along with this work; if not, write to the Free Software Foundation, 16 | # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 17 | # 18 | # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 19 | # or visit www.oracle.com if you need additional information or have any 20 | # questions. 21 | 22 | # 23 | # Log class for the adaptived functional tests 24 | # 25 | # Note: based on libcgroup's ftests.py 26 | # 27 | # 28 | 29 | import datetime 30 | import consts 31 | 32 | log_level = consts.DEFAULT_LOG_LEVEL 33 | log_file = consts.DEFAULT_LOG_FILE 34 | log_fd = None 35 | 36 | 37 | class Log(object): 38 | 39 | @staticmethod 40 | def log(msg, msg_level=consts.DEFAULT_LOG_LEVEL): 41 | global log_level, log_file, log_fd 42 | 43 | if log_level >= msg_level: 44 | if log_fd is None: 45 | Log.open_logfd(log_file) 46 | 47 | timestamp = datetime.datetime.now().strftime('%b %d %H:%M:%S') 48 | log_fd.write('{}: {}\n'.format(timestamp, msg)) 49 | 50 | @staticmethod 51 | def open_logfd(log_file): 52 | global log_fd 53 | 54 | log_fd = open(log_file, 'a') 55 | 56 | @staticmethod 57 | def log_critical(msg): 58 | Log.log('CRITICAL: {}'.format(msg), consts.LOG_CRITICAL) 59 | 60 | @staticmethod 61 | def log_warning(msg): 62 | Log.log('WARNING: {}'.format(msg), consts.LOG_WARNING) 63 | 64 | @staticmethod 65 | def log_debug(msg): 66 | Log.log('DEBUG: {}'.format(msg), consts.LOG_DEBUG) 67 | 68 | # vim: set et ts=4 sw=4: 69 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/tod_validate.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. 8 | * 9 | * This code is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * version 2 for more details (a copy is included in the LICENSE file that 13 | * accompanied this code). 14 | * 15 | * You should have received a copy of the GNU General Public License version 16 | * 2 along with this work; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 | * 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 | * or visit www.oracle.com if you need additional information or have any 21 | * questions. 22 | */ 23 | /** 24 | * Effect to validate that a cause successfully fired 25 | * 26 | * Returns a positive integer to the main adaptived loop when 27 | * the validator main() is invoked. This will cause adaptived 28 | * to exit the main loop and can be useful for testing that 29 | * causes have executed properly 30 | * 31 | * 32 | */ 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | #include 40 | 41 | const int default_return_value = 7; 42 | 43 | const char * const tod_validate_name = "tod_validate"; 44 | 45 | struct validate_opts { 46 | int ret; 47 | }; 48 | 49 | int tod_validate_init(struct adaptived_effect * const eff, struct json_object *args_obj, 50 | const struct adaptived_cause * const cse) 51 | { 52 | struct validate_opts *opts; 53 | int ret = 0; 54 | 55 | opts = malloc(sizeof(struct validate_opts)); 56 | if (!opts) { 57 | ret = -ENOMEM; 58 | goto error; 59 | } 60 | opts->ret = default_return_value; 61 | 62 | ret = adaptived_parse_int(args_obj, "return_value", &opts->ret); 63 | if (ret) 64 | goto error; 65 | 66 | /* we have successfully setup the validate effect */ 67 | ret = adaptived_effect_set_data(eff, (void *)opts); 68 | if (ret) 69 | goto error; 70 | 71 | return ret; 72 | 73 | error: 74 | if (opts) 75 | free(opts); 76 | 77 | return ret; 78 | } 79 | 80 | int tod_validate_main(struct adaptived_effect * const eff) 81 | { 82 | struct validate_opts * opts; 83 | 84 | opts = (struct validate_opts *)adaptived_effect_get_data(eff); 85 | 86 | /* main() will negate our return value */ 87 | return -opts->ret; 88 | } 89 | 90 | void tod_validate_exit(struct adaptived_effect * const eff) 91 | { 92 | struct validate_opts *opts; 93 | 94 | opts = (struct validate_opts *)adaptived_effect_get_data(eff); 95 | 96 | free(opts); 97 | } 98 | 99 | const struct adaptived_effect_functions tod_validate_fns = { 100 | tod_validate_init, 101 | tod_validate_main, 102 | tod_validate_exit, 103 | }; 104 | -------------------------------------------------------------------------------- /adaptived/tests/ftests/utils.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024, Oracle and/or its affiliates. 2 | # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 | # 4 | # This code is free software; you can redistribute it and/or modify it 5 | # under the terms of the GNU General Public License version 2 only, as 6 | # published by the Free Software Foundation. 7 | # 8 | # This code is distributed in the hope that it will be useful, but WITHOUT 9 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11 | # version 2 for more details (a copy is included in the LICENSE file that 12 | # accompanied this code). 13 | # 14 | # You should have received a copy of the GNU General Public License version 15 | # 2 along with this work; if not, write to the Free Software Foundation, 16 | # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 17 | # 18 | # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 19 | # or visit www.oracle.com if you need additional information or have any 20 | # questions. 21 | 22 | # 23 | # Utility functions for the adaptived functional tests 24 | # 25 | # 26 | 27 | from run import Run 28 | import datetime 29 | 30 | NOW_TOKEN = '<< now' 31 | 32 | 33 | # function to indent a block of text by cnt number of spaces 34 | def indent(in_str, cnt): 35 | leading_indent = cnt * ' ' 36 | return ''.join(leading_indent + line for line in in_str.splitlines(True)) 37 | 38 | 39 | def __parse_now_token(token): 40 | math_op = int(token[len(NOW_TOKEN) : len(token) - len('>>')].replace(' ', '')) 41 | 42 | token_time = datetime.datetime.now() + datetime.timedelta(seconds=math_op) 43 | token_time_str = token_time.strftime('%H:%M:%S') 44 | return token_time_str 45 | 46 | 47 | # Find and replace magic tokens in config files. The caller is expected to 48 | # delete the out_filename during cleanup. 49 | def config_find_and_replace(in_filename, out_filename): 50 | tokens = [NOW_TOKEN] 51 | parsers = ['__parse_now_token'] 52 | 53 | with open(in_filename) as ifile: 54 | with open(out_filename, 'w') as ofile: 55 | 56 | for line in ifile.readlines(): 57 | for idx, token in enumerate(tokens): 58 | token_idx = line.find(token) 59 | if token_idx >= 0: 60 | end_idx = token_idx + line[token_idx:].index('>>') + 2 61 | parsed_val = eval(parsers[idx])(line[token_idx : end_idx]) 62 | 63 | ofile.write('{}{}{}'.format(line[:token_idx], parsed_val, 64 | line[end_idx:])) 65 | else: 66 | ofile.write(line) 67 | 68 | 69 | # vim: set et ts=4 sw=4: 70 | -------------------------------------------------------------------------------- /adaptived/tests/gunit/001-adaptived_get_pressure.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. 8 | * 9 | * This code is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * version 2 for more details (a copy is included in the LICENSE file that 13 | * accompanied this code). 14 | * 15 | * You should have received a copy of the GNU General Public License version 16 | * 2 along with this work; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 | * 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 | * or visit www.oracle.com if you need additional information or have any 21 | * questions. 22 | */ 23 | /** 24 | * adaptived googletest for adaptived_get_pressure() 25 | */ 26 | 27 | #include 28 | 29 | #include 30 | #include 31 | 32 | #include "gtest/gtest.h" 33 | 34 | static const char * const PRESSURE_FILE = "001-adaptived_get_pressure.pressure"; 35 | 36 | /* 37 | static const float SOME_10 = 1.23; 38 | static const float SOME_60 = 4.56; 39 | static const float SOME_300 = 7.89; 40 | static const long long SOME_TOTAL = 123456789; 41 | 42 | static const float FULL_10 = 9.87; 43 | static const float FULL_60 = 6.54; 44 | static const float FULL_300 = 3.21; 45 | static const long long FULL_TOTAL = 987654321; 46 | */ 47 | 48 | #define STRINGIFY(_val) #_val 49 | #define STR(_val) STRINGIFY(_val) 50 | 51 | #define SOME_10 1.23 52 | #define SOME_60 4.56 53 | #define SOME_300 7.89 54 | #define SOME_TOTAL 123456789 55 | 56 | #define FULL_10 9.87 57 | #define FULL_60 6.54 58 | #define FULL_300 3.21 59 | #define FULL_TOTAL 987654321 60 | 61 | #define SOME_LINE "some avg10=" STR(SOME_10) " avg60=" STR(SOME_60) \ 62 | " avg300=" STR(SOME_300) " total=" STR(SOME_TOTAL) "\n" 63 | #define FULL_LINE "full avg10=" STR(FULL_10) " avg60=" STR(FULL_60) \ 64 | " avg300=" STR(FULL_300) " total=" STR(FULL_TOTAL) 65 | 66 | 67 | class AdaptivedGetPressureTest : public ::testing::Test { 68 | protected: 69 | 70 | void SetUp() override { 71 | int ret, fd; 72 | 73 | fd = creat(PRESSURE_FILE, S_IRUSR | S_IWUSR); 74 | ASSERT_GT(fd, 0); 75 | 76 | ret = write(fd, SOME_LINE, strlen(SOME_LINE)); 77 | ASSERT_EQ(ret, (int)strlen(SOME_LINE)); 78 | ret = write(fd, FULL_LINE, strlen(FULL_LINE)); 79 | ASSERT_EQ(ret, (int)strlen(FULL_LINE)); 80 | 81 | close(fd); 82 | } 83 | 84 | void TearDown() override { 85 | int ret; 86 | 87 | ret = remove(PRESSURE_FILE); 88 | ASSERT_EQ(ret, 0); 89 | } 90 | }; 91 | 92 | TEST_F(AdaptivedGetPressureTest, GetPressure) 93 | { 94 | struct adaptived_pressure_snapshot ps; 95 | int ret; 96 | 97 | ret = adaptived_get_pressure(PRESSURE_FILE, &ps); 98 | ASSERT_EQ(ret, 0); 99 | 100 | EXPECT_NEAR(ps.some.avg10, SOME_10, 0.01); 101 | EXPECT_NEAR(ps.some.avg60, SOME_60, 0.01); 102 | EXPECT_NEAR(ps.some.avg300, SOME_300, 0.01); 103 | ASSERT_EQ(ps.some.total, SOME_TOTAL); 104 | 105 | EXPECT_NEAR(ps.full.avg10, FULL_10, 0.01); 106 | EXPECT_NEAR(ps.full.avg60, FULL_60, 0.01); 107 | EXPECT_NEAR(ps.full.avg300, FULL_300, 0.01); 108 | ASSERT_EQ(ps.full.total, FULL_TOTAL); 109 | } 110 | -------------------------------------------------------------------------------- /adaptived/tests/gunit/004-adaptived_farray_linear_regression.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. 8 | * 9 | * This code is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * version 2 for more details (a copy is included in the LICENSE file that 13 | * accompanied this code). 14 | * 15 | * You should have received a copy of the GNU General Public License version 16 | * 2 along with this work; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 | * 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 | * or visit www.oracle.com if you need additional information or have any 21 | * questions. 22 | */ 23 | /** 24 | * adaptived googletest for float_utils.c 25 | */ 26 | 27 | #include 28 | 29 | #include 30 | #include 31 | 32 | #include "gtest/gtest.h" 33 | #include "defines.h" 34 | 35 | class FarrayLinearRegressionTest : public ::testing::Test { 36 | }; 37 | 38 | TEST_F(FarrayLinearRegressionTest, IntervalOfOne) 39 | { 40 | float y[] = {94.6, 88.4, 92.5, 90.1, 84.3, 75.7, 75.9, 80.2, 65.8, 60.9, 62.3, 41 | 58.9, 58.5, 63.5, 55.4, 59.4, 56.3, 52.1, 51.1, 48.6, 47.9, 51.8, 42 | 50.3, 45.6, 43.2, 43.1, 46.2, 40.7, 38.9, 37.5, 35.9, 40.2, 38.7}; 43 | int y_len, ret; 44 | float interp_y; 45 | 46 | y_len = ARRAY_SIZE(y); 47 | 48 | ret = adaptived_farray_linear_regression(y, y_len, 1, -28, &interp_y); 49 | ASSERT_EQ(ret, 0); 50 | EXPECT_NEAR(interp_y, 79.29, 0.01); 51 | 52 | ret = adaptived_farray_linear_regression(y, y_len, 1, 0, &interp_y); 53 | ASSERT_EQ(ret, 0); 54 | EXPECT_NEAR(interp_y, 31.07, 0.01); 55 | 56 | ret = adaptived_farray_linear_regression(y, y_len, 1, 7, &interp_y); 57 | ASSERT_EQ(ret, 0); 58 | EXPECT_NEAR(interp_y, 19.01, 0.01); 59 | } 60 | 61 | TEST_F(FarrayLinearRegressionTest, IntervalOfTwo) 62 | { 63 | float y[] = {7.0, 8.0, 6.0, 10.0, 15.0, 12.0, 14.0, 17.0, 21.0, 26.0, 29.0}; 64 | int y_len, ret; 65 | float interp_y; 66 | 67 | y_len = ARRAY_SIZE(y); 68 | 69 | ret = adaptived_farray_linear_regression(y, y_len, 2, -20, &interp_y); 70 | ASSERT_EQ(ret, 0); 71 | EXPECT_NEAR(interp_y, 4.09, 0.01); 72 | 73 | ret = adaptived_farray_linear_regression(y, y_len, 2, -15, &interp_y); 74 | ASSERT_EQ(ret, 0); 75 | EXPECT_NEAR(interp_y, 9.55, 0.01); 76 | 77 | ret = adaptived_farray_linear_regression(y, y_len, 2, 1, &interp_y); 78 | ASSERT_EQ(ret, 0); 79 | EXPECT_NEAR(interp_y, 27.0, 0.01); 80 | 81 | ret = adaptived_farray_linear_regression(y, y_len, 2, 20, &interp_y); 82 | ASSERT_EQ(ret, 0); 83 | EXPECT_NEAR(interp_y, 47.73, 0.01); 84 | } 85 | -------------------------------------------------------------------------------- /adaptived/tests/gunit/005-cgroup_long_long.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. 8 | * 9 | * This code is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * version 2 for more details (a copy is included in the LICENSE file that 13 | * accompanied this code). 14 | * 15 | * You should have received a copy of the GNU General Public License version 16 | * 2 along with this work; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 | * 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 | * or visit www.oracle.com if you need additional information or have any 21 | * questions. 22 | */ 23 | /** 24 | * adaptived googletest for adaptived_cgroup_[get|set]_long_long() 25 | */ 26 | 27 | #include 28 | #include 29 | 30 | #include "gtest/gtest.h" 31 | 32 | class CgroupLongLongTest : public ::testing::Test { 33 | }; 34 | 35 | static void CreateFile(const char * const filename, const char * const contents) 36 | { 37 | FILE *f; 38 | 39 | f = fopen(filename, "w"); 40 | ASSERT_NE(f, nullptr); 41 | 42 | fprintf(f, "%s", contents); 43 | fclose(f); 44 | } 45 | 46 | static void DeleteFile(const char * const filename) 47 | { 48 | remove(filename); 49 | } 50 | 51 | TEST_F(CgroupLongLongTest, InvalidSet) 52 | { 53 | int ret; 54 | 55 | ret = adaptived_cgroup_set_ll(NULL, 1234, 0); 56 | ASSERT_EQ(ret, -EINVAL); 57 | } 58 | 59 | TEST_F(CgroupLongLongTest, SetAndValidate) 60 | { 61 | char filename[] = "./CgroupLongLongSetAndValidate"; 62 | long long value = 65432; 63 | int ret; 64 | 65 | DeleteFile(filename); 66 | CreateFile(filename, "123456"); 67 | 68 | ret = adaptived_cgroup_set_ll(filename, value, ADAPTIVED_CGROUP_FLAGS_VALIDATE); 69 | ASSERT_EQ(ret, 0); 70 | 71 | DeleteFile(filename); 72 | } 73 | 74 | TEST_F(CgroupLongLongTest, InvalidGet) 75 | { 76 | char filename[] = "CgroupLongLongInvalidGet"; 77 | long long value; 78 | int ret; 79 | 80 | ret = adaptived_cgroup_get_ll(NULL, &value); 81 | ASSERT_EQ(ret, -EINVAL); 82 | 83 | ret = adaptived_cgroup_get_ll(filename, NULL); 84 | ASSERT_EQ(ret, -EINVAL); 85 | 86 | ret = adaptived_cgroup_get_ll(filename, &value); 87 | ASSERT_EQ(ret, -ENOENT); 88 | } 89 | 90 | TEST_F(CgroupLongLongTest, Get) 91 | { 92 | char filename[] = "./CgroupLongLongGet"; 93 | long long expected_value = 1357924680; 94 | char buf[FILENAME_MAX] = {0}; 95 | long long value; 96 | int ret; 97 | 98 | snprintf(buf, FILENAME_MAX - 1, "%lld\n", expected_value); 99 | 100 | CreateFile(filename, buf); 101 | 102 | ret = adaptived_cgroup_get_ll(filename, &value); 103 | ASSERT_EQ(ret, 0); 104 | ASSERT_EQ(value, expected_value); 105 | 106 | DeleteFile(filename); 107 | } 108 | -------------------------------------------------------------------------------- /adaptived/tests/gunit/006-cgroup_str.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. 8 | * 9 | * This code is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * version 2 for more details (a copy is included in the LICENSE file that 13 | * accompanied this code). 14 | * 15 | * You should have received a copy of the GNU General Public License version 16 | * 2 along with this work; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 | * 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 | * or visit www.oracle.com if you need additional information or have any 21 | * questions. 22 | */ 23 | /** 24 | * adaptived googletest for adaptived_cgroup_[get|set]_str() 25 | */ 26 | 27 | #include 28 | #include 29 | 30 | #include "gtest/gtest.h" 31 | 32 | class CgroupStringTest : public ::testing::Test { 33 | }; 34 | 35 | static void CreateFile(const char * const filename, const char * const contents) 36 | { 37 | FILE *f; 38 | 39 | f = fopen(filename, "w"); 40 | ASSERT_NE(f, nullptr); 41 | 42 | fprintf(f, "%s", contents); 43 | fclose(f); 44 | } 45 | 46 | static void DeleteFile(const char * const filename) 47 | { 48 | remove(filename); 49 | } 50 | 51 | TEST_F(CgroupStringTest, InvalidSet) 52 | { 53 | int ret; 54 | 55 | ret = adaptived_cgroup_set_str(NULL, "abcd", 0); 56 | ASSERT_EQ(ret, -EINVAL); 57 | 58 | ret = adaptived_cgroup_set_str("bad_filename", NULL, 0); 59 | ASSERT_EQ(ret, -EINVAL); 60 | } 61 | 62 | TEST_F(CgroupStringTest, SetAndValidate) 63 | { 64 | char filename[] = "./CgroupStringSetAndValidate"; 65 | char value[] = "abc123"; 66 | int ret; 67 | 68 | DeleteFile(filename); 69 | CreateFile(filename, "Hello World"); 70 | 71 | ret = adaptived_cgroup_set_str(filename, value, ADAPTIVED_CGROUP_FLAGS_VALIDATE); 72 | ASSERT_EQ(ret, 0); 73 | 74 | DeleteFile(filename); 75 | } 76 | 77 | TEST_F(CgroupStringTest, InvalidGet) 78 | { 79 | char filename[] = "CgroupStringInvalidGet"; 80 | char *value; 81 | int ret; 82 | 83 | ret = adaptived_cgroup_get_str(NULL, &value); 84 | ASSERT_EQ(ret, -EINVAL); 85 | 86 | ret = adaptived_cgroup_get_str(filename, NULL); 87 | ASSERT_EQ(ret, -EINVAL); 88 | 89 | ret = adaptived_cgroup_get_str(filename, &value); 90 | ASSERT_EQ(ret, -ENOENT); 91 | ASSERT_EQ(value, nullptr); 92 | } 93 | 94 | TEST_F(CgroupStringTest, Get) 95 | { 96 | char filename[] = "./CgroupStringGet"; 97 | char expected_value[] = "1234\n5678"; 98 | char *value; 99 | int ret; 100 | 101 | CreateFile(filename, expected_value); 102 | 103 | ret = adaptived_cgroup_get_str(filename, &value); 104 | ASSERT_EQ(ret, 0); 105 | ASSERT_STREQ(value, expected_value); 106 | 107 | free(value); 108 | 109 | DeleteFile(filename); 110 | } 111 | -------------------------------------------------------------------------------- /adaptived/tests/gunit/009-cgroup_detect.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. 8 | * 9 | * This code is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * version 2 for more details (a copy is included in the LICENSE file that 13 | * accompanied this code). 14 | * 15 | * You should have received a copy of the GNU General Public License version 16 | * 2 along with this work; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 | * 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 | * or visit www.oracle.com if you need additional information or have any 21 | * questions. 22 | */ 23 | /** 24 | * adaptived googletest for auto-detecting the cgroup value type 25 | */ 26 | 27 | #include 28 | #include 29 | 30 | #include "gtest/gtest.h" 31 | 32 | static const char * const llfile = "./test009.longlong"; 33 | static const char * const strfile = "./test009.string"; 34 | 35 | static const char * const llcontents = "123456789"; 36 | static const long long llcontents_ll = 123456789; /* must be the same as the line above */ 37 | static const char * const strcontents = "Soy un perdedor"; 38 | 39 | static void CreateFile(const char * const filename, const char * const contents) 40 | { 41 | FILE *f; 42 | 43 | f = fopen(filename, "w"); 44 | ASSERT_NE(f, nullptr); 45 | 46 | fprintf(f, "%s", contents); 47 | fclose(f); 48 | } 49 | 50 | static void DeleteFile(const char * const filename) 51 | { 52 | remove(filename); 53 | } 54 | 55 | class CgroupDetectTest : public ::testing::Test { 56 | protected: 57 | 58 | void SetUp() override { 59 | CreateFile(llfile, llcontents); 60 | CreateFile(strfile, strcontents); 61 | } 62 | 63 | void TearDown() override { 64 | DeleteFile(llfile); 65 | DeleteFile(strfile); 66 | } 67 | }; 68 | 69 | TEST_F(CgroupDetectTest, InvalidParams) 70 | { 71 | struct adaptived_cgroup_value value; 72 | int ret; 73 | 74 | ret = adaptived_cgroup_get_value(NULL, &value); 75 | ASSERT_EQ(ret, -EINVAL); 76 | 77 | ret = adaptived_cgroup_get_value(llfile, NULL); 78 | ASSERT_EQ(ret, -EINVAL); 79 | 80 | value.type = ADAPTIVED_CGVAL_DETECT; 81 | ret = adaptived_cgroup_set_value(llfile, &value, 0); 82 | ASSERT_EQ(ret, -EINVAL); 83 | } 84 | 85 | TEST_F(CgroupDetectTest, DetectLongLong) 86 | { 87 | struct adaptived_cgroup_value value; 88 | int ret; 89 | 90 | value.type = ADAPTIVED_CGVAL_DETECT; 91 | ret = adaptived_cgroup_get_value(llfile, &value); 92 | ASSERT_EQ(ret, 0); 93 | ASSERT_EQ(value.type, ADAPTIVED_CGVAL_LONG_LONG); 94 | ASSERT_EQ(value.value.ll_value, llcontents_ll); 95 | } 96 | 97 | TEST_F(CgroupDetectTest, DetectString) 98 | { 99 | struct adaptived_cgroup_value value; 100 | int ret; 101 | 102 | value.type = ADAPTIVED_CGVAL_DETECT; 103 | ret = adaptived_cgroup_get_value(strfile, &value); 104 | ASSERT_EQ(ret, 0); 105 | ASSERT_EQ(value.type, ADAPTIVED_CGVAL_STR); 106 | ASSERT_STREQ(value.value.str_value, strcontents); 107 | } 108 | -------------------------------------------------------------------------------- /adaptived/tests/gunit/011-kill_processes_sort.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024, Oracle and/or its affiliates. 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * 5 | * This code is free software; you can redistribute it and/or modify it 6 | * under the terms of the GNU General Public License version 2 only, as 7 | * published by the Free Software Foundation. 8 | * 9 | * This code is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * version 2 for more details (a copy is included in the LICENSE file that 13 | * accompanied this code). 14 | * 15 | * You should have received a copy of the GNU General Public License version 16 | * 2 along with this work; if not, write to the Free Software Foundation, 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 | * 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 | * or visit www.oracle.com if you need additional information or have any 21 | * questions. 22 | */ 23 | /** 24 | * adaptived googletest for _sort_pid_list() in src/effects/kill_processes.c 25 | */ 26 | 27 | #include 28 | 29 | #include 30 | #include 31 | 32 | #include "adaptived-internal.h" 33 | #include "gtest/gtest.h" 34 | #include "defines.h" 35 | 36 | /* TODO - delete this typedef when proc_pid_stats_utils.c is created */ 37 | struct pid_info { 38 | pid_t pid; 39 | long long vsize; 40 | }; 41 | 42 | static const int array_size = 10; 43 | static const long long vsizes[] = { 44 | 100, 45 | 50, 46 | 250, 47 | 1000, 48 | 400, 49 | 1500, 50 | 750, 51 | 50000, 52 | 0, 53 | 150, 54 | }; 55 | 56 | class SortPidListTest : public ::testing::Test { 57 | protected: 58 | 59 | void SetUp() override { 60 | ASSERT_EQ(array_size, (int)ARRAY_SIZE(vsizes)); 61 | } 62 | }; 63 | 64 | TEST_F(SortPidListTest, Sort) 65 | { 66 | struct pid_info pida[array_size] = { 0 }; 67 | int i; 68 | 69 | for (i = 0; i < array_size; i++) { 70 | pida[i].pid = i; 71 | pida[i].vsize = vsizes[i]; 72 | } 73 | 74 | qsort(pida, array_size, sizeof(struct pid_info), _sort_pid_list); 75 | 76 | ASSERT_EQ(pida[0].pid, 7); 77 | ASSERT_EQ(pida[1].pid, 5); 78 | ASSERT_EQ(pida[2].pid, 3); 79 | ASSERT_EQ(pida[3].pid, 6); 80 | ASSERT_EQ(pida[4].pid, 4); 81 | ASSERT_EQ(pida[5].pid, 2); 82 | ASSERT_EQ(pida[6].pid, 9); 83 | ASSERT_EQ(pida[7].pid, 0); 84 | ASSERT_EQ(pida[8].pid, 1); 85 | ASSERT_EQ(pida[9].pid, 8); 86 | } 87 | -------------------------------------------------------------------------------- /adaptived/tests/gunit/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CPPFLAGS = -I$(top_srcdir)/include \ 2 | -I$(top_srcdir)/src \ 3 | -I$(top_srcdir)/src/utils \ 4 | -I$(top_srcdir)/googletest/googletest/include \ 5 | -I$(top_srcdir)/googletest/googletest \ 6 | -std=c++11 \ 7 | -Wno-write-strings \ 8 | -Wall 9 | LDADD = $(top_builddir)/src/.libs/libadaptived.la 10 | 11 | EXTRA_DIST = $(top_srcdir)/googletest/googletest/libgtest.so \ 12 | $(top_srcdir)/googletest/googletest/libgtest_main.so \ 13 | $(top_srcdir)/googletest/googletest/include 14 | 15 | check_PROGRAMS = gtest 16 | TESTS = gtest 17 | 18 | gtest_SOURCES = gtest.cpp \ 19 | 001-adaptived_get_pressure.cpp \ 20 | 002-adaptived_get_pressure_avg.cpp \ 21 | 003-adaptived_farray_append.cpp \ 22 | 004-adaptived_farray_linear_regression.cpp \ 23 | 005-cgroup_long_long.cpp \ 24 | 006-cgroup_str.cpp \ 25 | 007-path_walk.cpp \ 26 | 008-cgroup_get_procs.cpp \ 27 | 009-cgroup_detect.cpp \ 28 | 010-adaptived_get_schedstats.cpp \ 29 | 011-kill_processes_sort.cpp 30 | 31 | gtest_LDFLAGS = -L$(top_srcdir)/googletest/googletest -l:libgtest.so \ 32 | -rpath $(abs_top_srcdir)/googletest/googletest 33 | 34 | check-build: 35 | ${MAKE} ${AM_MAKEFLAGS} ${check_PROGRAMS} 36 | -------------------------------------------------------------------------------- /adaptived/tests/gunit/gtest.cpp: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: LGPL-2.1-only */ 2 | /** 3 | * adaptived googletest main entry point 4 | * 5 | * Copyright (c) 2023 Oracle and/or its affiliates 6 | * Author: Tom Hromatka 7 | */ 8 | 9 | #include "gtest/gtest.h" 10 | 11 | int main(int argc, char **argv) 12 | { 13 | ::testing::InitGoogleTest(&argc, argv); 14 | 15 | return RUN_ALL_TESTS(); 16 | } 17 | -------------------------------------------------------------------------------- /adaptivemm/50-adaptivemm.preset: -------------------------------------------------------------------------------- 1 | # Enable adaptivemm service since it is essential to managing free 2 | # memory on the system proactively and reducing memory allocation stalls 3 | 4 | enable adaptivemmd.service 5 | -------------------------------------------------------------------------------- /adaptivemm/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to this repository 2 | 3 | We welcome your contributions! There are multiple ways to contribute. 4 | 5 | ## Opening issues 6 | 7 | For bugs or enhancement requests, please file a GitHub issue unless it's 8 | security related. When filing a bug remember that the better written the bug is, 9 | the more likely it is to be fixed. If you think you've found a security 10 | vulnerability, do not raise a GitHub issue and follow the instructions in our 11 | [security policy](./SECURITY.md). 12 | 13 | ## Contributing code 14 | 15 | We welcome your code contributions. Before submitting code via a pull request, 16 | you will need to have signed the [Oracle Contributor Agreement][OCA] (OCA) and 17 | your commits need to include the following line using the name and e-mail 18 | address you used to sign the OCA: 19 | 20 | ```text 21 | Signed-off-by: Your Name 22 | ``` 23 | 24 | This can be automatically added to pull requests by committing with `--sign-off` 25 | or `-s`, e.g. 26 | 27 | ```text 28 | git commit --signoff 29 | ``` 30 | 31 | Only pull requests from committers that can be verified as having signed the OCA 32 | can be accepted. 33 | 34 | ## Pull request process 35 | 36 | 1. Ensure there is an issue created to track and discuss the fix or enhancement 37 | you intend to submit. 38 | 1. Fork this repository. 39 | 1. Create a branch in your fork to implement the changes. We recommend using 40 | the issue number as part of your branch name, e.g. `1234-fixes`. 41 | 1. Ensure that any documentation is updated with the changes that are required 42 | by your change. 43 | 1. Ensure that any samples are updated if the base image has been changed. 44 | 1. Submit the pull request. *Do not leave the pull request blank*. Explain exactly 45 | what your changes are meant to do and provide simple steps on how to validate. 46 | your changes. Ensure that you reference the issue you created as well. 47 | 1. We will assign the pull request to 2-3 people for review before it is merged. 48 | 49 | ## Code of conduct 50 | 51 | Follow the [Golden Rule](https://en.wikipedia.org/wiki/Golden_Rule). If you'd 52 | like more specific guidelines, see the [Contributor Covenant Code of Conduct][COC]. 53 | 54 | [OCA]: https://oca.opensource.oracle.com 55 | [COC]: https://www.contributor-covenant.org/version/1/4/code-of-conduct/ 56 | -------------------------------------------------------------------------------- /adaptivemm/SECURITY.md: -------------------------------------------------------------------------------- 1 | # Reporting security vulnerabilities 2 | 3 | Oracle values the independent security research community and believes that 4 | responsible disclosure of security vulnerabilities helps us ensure the security 5 | and privacy of all our users. 6 | 7 | Please do NOT raise a GitHub Issue to report a security vulnerability. If you 8 | believe you have found a security vulnerability, please submit a report to 9 | [secalert_us@oracle.com][1] preferably with a proof of concept. Please review 10 | some additional information on [how to report security vulnerabilities to Oracle][2]. 11 | We encourage people who contact Oracle Security to use email encryption using 12 | [our encryption key][3]. 13 | 14 | We ask that you do not use other channels or contact the project maintainers 15 | directly. 16 | 17 | Non-vulnerability related security issues including ideas for new or improved 18 | security features are welcome on GitHub Issues. 19 | 20 | ## Security updates, alerts and bulletins 21 | 22 | Security updates will be released on a regular cadence. Many of our projects 23 | will typically release security fixes in conjunction with the 24 | Oracle Critical Patch Update program. Additional 25 | information, including past advisories, is available on our [security alerts][4] 26 | page. 27 | 28 | ## Security-related information 29 | 30 | We will provide security related information such as a threat model, considerations 31 | for secure use, or any known security issues in our documentation. Please note 32 | that labs and sample code are intended to demonstrate a concept and may not be 33 | sufficiently hardened for production use. 34 | 35 | [1]: mailto:secalert_us@oracle.com 36 | [2]: https://www.oracle.com/corporate/security-practices/assurance/vulnerability/reporting.html 37 | [3]: https://www.oracle.com/security-alerts/encryptionkey.html 38 | [4]: https://www.oracle.com/security-alerts/ 39 | -------------------------------------------------------------------------------- /adaptivemm/adaptivemmd.cfg: -------------------------------------------------------------------------------- 1 | # Configuration file for adaptivemmd 2 | # 3 | # Options in this file can be overridden with command line options 4 | 5 | # verbosity level (1-5) 6 | VERBOSE=0 7 | 8 | # Aggressiveness level for adaptivemmd (1-3) 9 | AGGRESSIVENESS=2 10 | 11 | # ============================ 12 | # Free page management section 13 | # ============================ 14 | # Enable management of free pages through watermarks tuning 15 | ENABLE_FREE_PAGE_MGMT=1 16 | 17 | # Guidance for tuning of vm.vfs_cache_pressure 18 | PREFER_OBJECT_CACHING=1 19 | 20 | # Maximum gap between low and high watermarks (in GB) 21 | # MAXGAP=5 22 | 23 | # ================================== 24 | # Negative dentry management section 25 | # ================================== 26 | # Enable management of negative dentry cap 27 | ENABLE_NEG_DENTRY_MGMT=1 28 | 29 | # Cap for memory consumed by negative dentries as a fraction of 1000. 30 | # Range of values supported by kernel is 1-100. 31 | # NOTE: for kernels with support for this functionality 32 | # (Hint: look for /proc/sys/fs/negative-dentry-limit) 33 | NEG_DENTRY_CAP=15 34 | 35 | # ============================== 36 | # Memory leack detection section 37 | # ============================== 38 | # Enable checks for possible memory leaks 39 | ENABLE_MEMLEAK_CHECK=1 40 | -------------------------------------------------------------------------------- /adaptivemm/adaptivemmd.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Adaptive free memory optimizer daemon 3 | Documentation=man:adaptivemmd(8) 4 | After=systemd-sysctl.service local-fs.target syslog.target 5 | 6 | [Service] 7 | Type=forking 8 | EnvironmentFile=-/etc/sysconfig/adaptivemmd 9 | ExecStart=/usr/sbin/adaptivemmd 10 | KillMode=control-group 11 | Restart=on-failure 12 | RestartSec=10s 13 | 14 | [Install] 15 | WantedBy=multi-user.target 16 | -------------------------------------------------------------------------------- /adaptivemm/src/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS=-I. -Wall -g 3 | LDFLAGS= 4 | OBJS=predict.o adaptivemmd.o 5 | 6 | .DEFAULT_GOAL := adaptivemmd 7 | 8 | all: adaptivemmd 9 | 10 | predict.o: predict.c predict.h 11 | $(CC) -c -o $@ $< $(CFLAGS) 12 | 13 | adaptivemmd.o: adaptivemmd.c predict.h 14 | $(CC) -c -o $@ $< $(CFLAGS) 15 | 16 | adaptivemmd: $(OBJS) 17 | $(CC) -o $@ $^ $(LDFLAGS) 18 | 19 | clean: 20 | rm -f $(OBJS) adaptivemmd cscope.* 21 | 22 | -------------------------------------------------------------------------------- /adaptivemm/src/predict.h: -------------------------------------------------------------------------------- 1 | /* 2 | * * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. 3 | * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 | * * 5 | * * This code is free software; you can redistribute it and/or modify it 6 | * * under the terms of the GNU General Public License version 2 only, as 7 | * * published by the Free Software Foundation. 8 | * * 9 | * * This code is distributed in the hope that it will be useful, but WITHOUT 10 | * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * * version 2 for more details (a copy is included in the LICENSE file that 13 | * * accompanied this code). 14 | * * 15 | * * You should have received a copy of the GNU General Public License version 16 | * * 2 along with this work; if not, write to the Free Software Foundation, 17 | * * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 | * * 19 | * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 | * * or visit www.oracle.com if you need additional information or have any 21 | * * questions. 22 | * */ 23 | #ifndef PREDICT_H 24 | #define PREDICT_H 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | /* Size of sliding window for computing trend line */ 38 | #define LSQ_LOOKBACK 8 39 | 40 | /* How often should data be sampled and trend analyzed*/ 41 | #define LOW_PERIODICITY 60 42 | #define NORM_PERIODICITY 30 43 | #define HIGH_PERIODICITY 15 44 | 45 | #define MAX_ORDER 11 46 | #define MEMPREDICT_RECLAIM 0x01 47 | #define MEMPREDICT_COMPACT 0x02 48 | #define MEMPREDICT_LOWER_WMARKS 0x04 49 | 50 | extern long compaction_rate, reclaim_rate; 51 | extern int debug_mode, verbose, max_compaction_order, periodicity; 52 | 53 | struct lsq_struct { 54 | int next; 55 | int ready; 56 | long long y[LSQ_LOOKBACK]; 57 | long long x[LSQ_LOOKBACK]; 58 | }; 59 | 60 | enum output_type { 61 | OUTPUT_OBSERVATIONS, 62 | OUTPUT_PREDICTIONS, 63 | MAX_OUTPUT 64 | }; 65 | 66 | struct frag_info { 67 | long long free_pages; 68 | long long msecs; 69 | }; 70 | 71 | 72 | int lsq_fit(struct lsq_struct *lsq, long long new_y, long long new_x, 73 | long long *m, long long *c); 74 | 75 | unsigned long predict(struct frag_info *, struct lsq_struct *, 76 | unsigned long, unsigned long, int); 77 | 78 | #define log_err(...) log_msg(LOG_ERR, __VA_ARGS__) 79 | #define log_warn(...) log_msg(LOG_WARNING, __VA_ARGS__) 80 | #define log_dbg(...) if (debug_mode) \ 81 | log_msg(LOG_DEBUG, __VA_ARGS__) 82 | #define log_info(verb_level, ...) if (verbose >= verb_level) \ 83 | log_msg(LOG_INFO, __VA_ARGS__) 84 | 85 | /* Use pr_info to log info irrespective of verbosity level */ 86 | #define pr_info(...) log_msg(LOG_INFO, __VA_ARGS__) 87 | 88 | extern void log_msg(int level, char *fmt, ...); 89 | 90 | #ifdef __cplusplus 91 | } 92 | #endif 93 | 94 | #endif /* PREDICT_H */ 95 | -------------------------------------------------------------------------------- /tools/build_spec.yaml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023, 2022, Oracle and/or its affiliates. 2 | 3 | version: 0.1 4 | component: build 5 | timeoutInSeconds: 1000 6 | shell: bash 7 | 8 | steps: 9 | - type: Command 10 | name: "compress the repo" 11 | command: | 12 | tar -cvzf ${OCI_WORKSPACE_DIR}/repo.tgz ./ 13 | outputArtifacts: 14 | - name: artifact 15 | type: BINARY 16 | location: ${OCI_WORKSPACE_DIR}/repo.tgz 17 | -------------------------------------------------------------------------------- /tools/diff.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ADAPTIVED=0 4 | ADAPTIVEMM=0 5 | 6 | ADAPTIVEMM_FILES=( 7 | "adaptivemmd.8" 8 | "adaptivemmd.c" 9 | "adaptivemmd.cfg" 10 | "adaptivemmd.service" 11 | "adaptivemm.spec" 12 | "build_spec.yaml" 13 | "CONTRIBUTING.md" 14 | "LICENSE.txt" 15 | "Makefile" 16 | "predict.c" 17 | "predict.h" 18 | "README.md" 19 | "SECURITY.md" 20 | ) 21 | 22 | RETURN_ADAPTIVED=false 23 | 24 | START_HASH="origin/master" 25 | END_HASH="HEAD" 26 | 27 | VERBOSE=false 28 | PRINTED_FILES=false 29 | 30 | while getopts demsv option 31 | do 32 | case "${option}" 33 | in 34 | d) RETURN_ADAPTIVED=true;; 35 | e) 36 | eval nextopt=\${$OPTIND} 37 | if [[ -n $nextopt && $nextopt != -* ]] ; then 38 | OPTIND=$((OPTIND + 1)) 39 | END_HASH=$nextopt 40 | fi 41 | ;; 42 | m) RETURN_ADAPTIVED=false;; 43 | s) 44 | eval nextopt=\${$OPTIND} 45 | if [[ -n $nextopt && $nextopt != -* ]] ; then 46 | OPTIND=$((OPTIND + 1)) 47 | START_HASH=$nextopt 48 | fi 49 | ;; 50 | v) VERBOSE=true;; 51 | esac 52 | done 53 | 54 | if [[ $RETURN_ADAPTIVED == true ]]; 55 | then 56 | DIR=adaptived/ 57 | else 58 | DIR=adaptivemm/ 59 | fi 60 | CMD="git diff --name-only $START_HASH..$END_HASH $DIR" 61 | FILES=$($CMD) 62 | 63 | if [[ $VERBOSE == true ]]; 64 | then 65 | echo "$CMD" 66 | echo "-------------------------------" 67 | fi 68 | 69 | for FILE in $FILES; 70 | do 71 | if [[ $FILE == adaptived/* ]]; 72 | then 73 | ADAPTIVED=1 74 | 75 | if [[ $VERBOSE == true ]]; 76 | then 77 | echo "$FILE" 78 | PRINTED_FILES=true 79 | fi 80 | fi 81 | 82 | for AMM_FILE in ${ADAPTIVEMM_FILES[@]}; 83 | do 84 | if [[ $FILE == $AMM_FILE ]]; 85 | then 86 | ADAPTIVEMM=1 87 | 88 | if [[ $VERBOSE == true ]]; 89 | then 90 | echo "$FILE" 91 | PRINTED_FILES=true 92 | fi 93 | fi 94 | done 95 | done 96 | 97 | 98 | if [[ $VERBOSE == true ]]; 99 | then 100 | if [[ $PRINTED_FILES == false ]]; 101 | then 102 | echo "No files were modified" 103 | fi 104 | fi 105 | 106 | if [[ $RETURN_ADAPTIVED == true ]]; 107 | then 108 | if [[ $VERBOSE == true ]]; 109 | then 110 | echo "-------------------------------" 111 | else 112 | echo $ADAPTIVED 113 | fi 114 | else 115 | if [[ $VERBOSE == true ]]; 116 | then 117 | echo "-------------------------------" 118 | else 119 | echo $ADAPTIVEMM 120 | fi 121 | fi 122 | 123 | exit 0 124 | --------------------------------------------------------------------------------