Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pants-plugins/uses_services to check before running tests for required services (like mongo) #5864

Merged
merged 71 commits into from
Feb 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
b7e53da
add v1 pants-plugin/uses_services
cognifloyd May 13, 2021
fbf9caa
stub instructions for mongo service
cognifloyd May 13, 2021
896c87b
improve mongo_is_running stub to check only once per pants run
cognifloyd May 13, 2021
de0a297
rules are async
cognifloyd May 13, 2021
bf26223
add rule for platform introspection
cognifloyd May 13, 2021
a0cd789
introspect platform
cognifloyd May 14, 2021
4c4f5b6
platform introspection in a Process()
cognifloyd May 14, 2021
90bc769
use pex to provide distro requirement
cognifloyd May 15, 2021
b00fbb2
use open to get script contents
cognifloyd May 15, 2021
3690617
Use PathGlobs to get the inspect_platform script
cognifloyd May 15, 2021
03feaf1
Error if script is moved
cognifloyd May 15, 2021
a9590cc
use platform object in mongo
cognifloyd May 15, 2021
e92c219
Add mongo install instructions
cognifloyd May 15, 2021
acb5b30
add basic instructions for Mac
cognifloyd May 15, 2021
172247f
enhance exception to include platform info
cognifloyd May 15, 2021
cfc932a
use right instructions per platform
cognifloyd May 15, 2021
59e72e8
add note
cognifloyd May 15, 2021
c9bfed1
revert to open() file per feedback in slack
cognifloyd May 15, 2021
392f1b9
notes on db host,port,name used in tests
cognifloyd May 16, 2021
acdc8fa
add __all__ to inspect_platform
cognifloyd May 16, 2021
e07ea59
add is_mongo_running check to pants-plugin
cognifloyd May 16, 2021
299f962
do not shadow platform module
cognifloyd May 18, 2021
090b4cb
pants: clean up uses_services pants plugin
cognifloyd May 19, 2021
6e05dca
pants: shortform Get has to have only 1 comma
cognifloyd May 19, 2021
6bb5a2e
pants: cleanup use_services plugin
cognifloyd May 20, 2021
c4f3e24
pants: fix uses_services plugin registration
cognifloyd May 20, 2021
1def4e5
pants: fix uses_services so it works
cognifloyd May 20, 2021
e7c1e60
pants: do not cache check for mongodb service
cognifloyd May 20, 2021
a42676f
pants: clean up imports in uses_services plugin
cognifloyd May 21, 2021
33aef47
pants: use MultiGet in pants plugin
cognifloyd May 21, 2021
a445005
pants: combine mongo_is_running rules
cognifloyd May 21, 2021
6346ffa
pants: add LogLevel to rules so they show up in UI
cognifloyd May 21, 2021
b221cb0
pants: tailor
cognifloyd May 22, 2021
73315a5
pants: fix error importing uses_services plugin
cognifloyd May 22, 2021
036e1ac
pants: reformat plugins with black
cognifloyd May 31, 2021
3f4d70a
pants: update ProcessCacheScope in uses_services plugin
cognifloyd Jun 8, 2021
fcd9376
reformat with black
cognifloyd Dec 11, 2022
5e2e609
add license header
cognifloyd Jun 14, 2021
e741af5
fix flake8 identified issues
cognifloyd Jun 14, 2021
f02f6de
update pants-plugin apis from pants 2.7 to 2.8
cognifloyd May 26, 2022
0d73cd7
update pants-plugins plugin apis from 2.12 to 2.13.0a1
cognifloyd Jul 1, 2022
8c0d6b8
drop now unused [GLOBAL].plugins in pants.toml
cognifloyd Dec 11, 2022
e517c7a
pants: Mark more tests with uses=["mongo"]
cognifloyd May 19, 2021
8c9941a
update db notes in pants-plugins/uses_services
cognifloyd Dec 11, 2022
0352ccf
update pants-plugins/uses_services copyright to 2023
cognifloyd Jan 5, 2023
048d035
include "rules" in uses_services rule file names
cognifloyd Jan 7, 2023
ee4a4cc
add dependent rules to uses_services plugin
cognifloyd Jan 7, 2023
4605244
fix typos in uses_services plugin
cognifloyd Jan 7, 2023
d83ab19
add test for uses_services get_platform rule
cognifloyd Jan 7, 2023
c1ea512
separate pytest-specific rule from generic mongo_is_running rule
cognifloyd Jan 7, 2023
9ef1f38
refactor uses_services plugin + comments
cognifloyd Jan 7, 2023
7d9320d
add test for uses_services plugin mongo rule
cognifloyd Jan 7, 2023
571c341
add description of uses_services plugin to pants-plugins/README.md
cognifloyd Jan 8, 2023
29fbefa
reformat with black
cognifloyd Jan 9, 2023
37816fc
enable pants-plugins/uses_services mongo test_is_running
cognifloyd Jan 9, 2023
a46328c
satisfy flake8
cognifloyd Jan 9, 2023
64b149d
reformat with black
cognifloyd Jan 9, 2023
f82a4f3
cleanup uses_services plugin test names/comments
cognifloyd Jan 9, 2023
84dd957
more consistent & drop unused test bits
cognifloyd Jan 10, 2023
cabfdfe
flake8
cognifloyd Jan 10, 2023
d8b423f
more samples
cognifloyd Jan 23, 2023
b76147d
move platform_sample test cases to separate file for reusability
cognifloyd Jan 25, 2023
a44d3ad
drop windows platform fixture I guessed on
cognifloyd Jan 25, 2023
fc69b66
expand instructions
cognifloyd Jan 25, 2023
2df21cb
standardize ServiceMissingError messages
cognifloyd Jan 25, 2023
6f41b21
include sudo in instructions
cognifloyd Jan 26, 2023
c800d3b
cleanup BUILD file
cognifloyd Jan 26, 2023
f9b607b
finish updating interface of ServiceSpecificMessages
cognifloyd Jan 26, 2023
30e6263
avoid cirucular use of `pants-plugins/uses_services` before the tests…
cognifloyd Jan 27, 2023
ffe161f
update changelog entry
cognifloyd Jan 9, 2023
5e18f3e
grammar/typo fix
cognifloyd Jan 28, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ jobs:
python-version-short: '3.8'
python-version: '3.8.10'

services:
mongo:
image: mongo:4.4
ports:
- 27017:27017

env:
COLUMNS: '120'

Expand Down
2 changes: 1 addition & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Added
working on StackStorm, improve our security posture, and improve CI reliability thanks in part
to pants' use of PEX lockfiles. This is not a user-facing addition.
#5778 #5789 #5817 #5795 #5830 #5833 #5834 #5841 #5840 #5838 #5842 #5837 #5849 #5850
#5846 #5853 #5848 #5847 #5858 #5857 #5860 #5868 #5871
#5846 #5853 #5848 #5847 #5858 #5857 #5860 #5868 #5871 #5864
Contributed by @cognifloyd

* Added a joint index to solve the problem of slow mongo queries for scheduled executions. #5805
Expand Down
13 changes: 13 additions & 0 deletions pants-plugins/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ The plugins here add custom goals or other logic into pants.

To see available goals, do "./pants help goals" and "./pants help $goal".

These plugins might be useful outside of the StackStorm project:
- `uses_services`

These StackStorm-specific plugins might be useful in other StackStorm-related repos.
- `pack_metadata`

Expand Down Expand Up @@ -66,3 +69,13 @@ the `fmt` goal (eg `./pants fmt contrib/schemas::`), the schemas will
be regenerated if any of the files used to generate them have changed.
Also, running the `lint` goal will fail if the schemas need to be
regenerated.

### `uses_seevices` plugin

This plugin validates that services are running if required. For example, some tests
need mongo, so this plugin can ensure mongo is running. If it is not running, then
an error with instructions on how to run it are given to the user.

`uses_services` has some StackStorm-specific assumptions in it, but it might be
generalizable. There are several other StackStorm-specific plugins, but some of
them are only useful in the st2 repo.
19 changes: 19 additions & 0 deletions pants-plugins/uses_services/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
python_sources(
sources=["*.py", "!*_test.py", "!data_fixtures.py"],
)

python_test_utils(
name="test_utils",
sources=["data_fixtures.py"],
)

python_tests(
name="tests",
# Do not enable `uses` for these tests.
# These tests still need the running services, but if the plugin
# is somehow broken, then any failures would prevent these tests
# from running to tell us what is wrong.
# overrides={
# "mongo_rules_test.py": {"uses": ["mongo"]},
# },
)
Empty file.
144 changes: 144 additions & 0 deletions pants-plugins/uses_services/data_fixtures.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# Copyright 2023 The StackStorm Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import annotations

from .platform_rules import Platform


def platform(
arch="",
os="",
distro="",
distro_name="",
distro_codename="",
distro_like="",
distro_major_version="",
distro_version="",
mac_release="",
win_release="",
) -> Platform:
"""Create a Platform with all values defaulted to the empty string."""
return Platform(
arch=arch,
os=os,
distro=distro,
distro_name=distro_name,
distro_codename=distro_codename,
distro_like=distro_like,
distro_major_version=distro_major_version,
distro_version=distro_version,
mac_release=mac_release,
win_release=win_release,
)


platform_samples = (
platform(), # empty
# EL distros ##################
platform(
arch="x86_64",
os="Linux",
distro="centos",
distro_name="Centos Linux",
distro_codename="Core",
distro_like="rhel fedora",
distro_major_version="7",
distro_version="7",
),
platform(
arch="x86_64",
os="Linux",
distro="rocky",
distro_name="Rocky Linux",
distro_codename="Green Obsidian",
distro_like="rhel centos fedora",
distro_major_version="8",
distro_version="8.7",
),
# debian distros ##############
platform(
arch="x86_64",
os="Linux",
distro="ubuntu",
distro_name="Ubuntu",
distro_codename="xenial",
distro_like="debian",
distro_major_version="16",
distro_version="16.04",
),
platform(
arch="x86_64",
os="Linux",
distro="ubuntu",
distro_name="Ubuntu",
distro_codename="bionic",
distro_like="debian",
distro_major_version="18",
distro_version="18.04",
),
platform(
arch="x86_64",
os="Linux",
distro="ubuntu",
distro_name="Ubuntu",
distro_codename="focal",
distro_like="debian",
distro_major_version="20",
distro_version="20.04",
),
# other Linux distros #########
platform(
arch="x86_64",
os="Linux",
distro="gentoo",
distro_name="Gentoo",
distro_codename="n/a",
distro_major_version="2",
distro_version="2.7",
),
platform(
arch="aarch64",
os="Linux",
# no distro in termux on android
),
# platform(
# arch="x86_64",
# os="Linux",
# distro="",
# distro_name="",
# distro_codename="",
# distro_like="",
# distro_major_version="",
# distro_version="",
# ),
# Mac OS X ####################
platform(
arch="x86_64",
os="Darwin",
distro="darwin",
distro_name="Darwin",
distro_major_version="19",
distro_version="19.6.0",
mac_release="10.15.7",
),
platform(
arch="x86_64",
os="Darwin",
distro="darwin",
distro_name="Darwin",
distro_major_version="21",
distro_version="21.6.0",
mac_release="12.6.2",
),
)
167 changes: 167 additions & 0 deletions pants-plugins/uses_services/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
# Copyright 2023 The StackStorm Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import annotations

from dataclasses import dataclass
from textwrap import dedent

from uses_services.platform_rules import Platform


@dataclass(frozen=True)
class ServiceSpecificMessages:
service: str

service_start_cmd_el_7: str
service_start_cmd_el: str
not_installed_clause_el: str
install_instructions_el: str

service_start_cmd_deb: str
not_installed_clause_deb: str
install_instructions_deb: str

service_start_cmd_generic: str


class ServiceMissingError(Exception):
"""Error raised when a test uses a service but that service is missing."""

def __init__(
self, service: str, platform: Platform, instructions: str = "", msg=None
):
if msg is None:
msg = f"The {service} service does not seem to be running or is not accessible!"
if instructions:
msg += f"\n{instructions}"
super().__init__(msg)
self.service = service
self.platform = platform
self.instructions = instructions

@classmethod
def generate(
cls, platform: Platform, messages: ServiceSpecificMessages
) -> ServiceMissingError:
service = messages.service

supported = False
if platform.distro in ["centos", "rhel"] or "rhel" in platform.distro_like:
supported = True
if platform.distro_major_version == "7":
service_start_cmd = messages.service_start_cmd_el_7
else:
service_start_cmd = messages.service_start_cmd_el
not_installed_clause = messages.not_installed_clause_el
install_instructions = messages.install_instructions_el

elif (
platform.distro in ["ubuntu", "debian"] or "debian" in platform.distro_like
):
supported = True
service_start_cmd = messages.service_start_cmd_deb
not_installed_clause = messages.not_installed_clause_deb
install_instructions = messages.install_instructions_deb

if supported:
instructions = dedent(
f"""\
If {service} is installed, but not running try:

{service_start_cmd}

If {service} is not installed, {not_installed_clause}:

"""
).format(
service=service,
service_start_cmd=service_start_cmd,
not_installed_clause=not_installed_clause,
)
instructions += install_instructions
elif platform.os == "Linux":
instructions = dedent(
f"""\
You are on Linux using {platform.distro_name}, which is not
one of our generally supported distributions. We recommend
you use vagrant for local development with something like:

vagrant init stackstorm/st2
vagrant up
vagrant ssh

Please see: https://docs.stackstorm.com/install/vagrant.html

For anyone who wants to attempt local development without vagrant,
you are pretty much on your own. At a minimum you need to install
and start {service} with something like:

{messages.service_start_cmd_generic}

We would be interested to hear about alternative distros people
are using for development. If you are able, please let us know
on slack which distro you are using:

Arch: {platform.arch}
Distro: {platform.distro}
Distro Name: {platform.distro_name}
Distro Codename: {platform.distro_codename}
Distro Family: {platform.distro_like}
Distro Major Version: {platform.distro_major_version}
Distro Version: {platform.distro_version}

Thanks and Good Luck!
"""
)
elif platform.os == "Darwin": # MacOS
instructions = dedent(
f"""\
You are on Mac OS. Generally we recommend using vagrant for local
development on Mac OS with something like:

vagrant init stackstorm/st2
vagrant up
vagrant ssh

Please see: https://docs.stackstorm.com/install/vagrant.html

For anyone who wants to attempt local development without vagrant,
you may run into some speed bumps. Other StackStorm developers have
been known to use Mac OS for development, so feel free to ask for
help in slack. At a minimum you need to install and start {service}.
"""
)
else:
instructions = dedent(
f"""\
You are not on Linux. In this case we recommend using vagrant
for local development with something like:

vagrant init stackstorm/st2
vagrant up
vagrant ssh

Please see: https://docs.stackstorm.com/install/vagrant.html

For anyone who wants to attempt local development without vagrant,
you are pretty much on your own. At a minimum you need to install
and start {service}. Good luck!
"""
)

return cls(
service=service,
platform=platform,
instructions=instructions,
)
Loading