Skip to content

Commit 3b8f856

Browse files
committed
feat: add copilot instruction
Signed-off-by: Jack Yu <[email protected]>
1 parent ac32dd6 commit 3b8f856

File tree

1 file changed

+124
-0
lines changed

1 file changed

+124
-0
lines changed
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
---
2+
applyTo: '**'
3+
---
4+
5+
## Must Do
6+
7+
- When writing **integration tests**, refer to the existing tests under the `tests/harvester_e2e_tests/integrations` directory.
8+
- When writing **API tests**, refer to the existing tests under the `tests/harvester_e2e_tests/apis` directory.
9+
- If you mention "shared in the class" or "sharing in the class", make sure the `@pytest.fixture` scope is set to `class`. Use a `yield` statement to define the shared fixture.
10+
- Each test case **must include at least one passing and one failing scenario**.
11+
- **All comments must be written in English** — do not use other languages.
12+
13+
### Must Do for Harvester API
14+
15+
- When adding a new Harvester API and the corresponding resource **does not already exist** under `apiclient/harvester_api/managers`, create a new file with the **plural form** of the resource name.
16+
- For example, if the resource is "image", search for `apiclient/harvester_api/managers/image.py` or `apiclient/harvester_api/managers/images.py`.
17+
- Load the new resource in `apiclient/harvester_api/api.py` and register it in `apiclient/harvester_api/managers/__init__.py`.
18+
- Refer to `apiclient/harvester_api/managers/images.py` as a sample implementation.
19+
- Follow these standard status codes to validate Harvester API responses:
20+
- `201` → Resource successfully created
21+
- `200` → Operation succeeded (general case)
22+
23+
## Don't Do
24+
25+
- Do **not** use method names with `_` prefixes in tests, such as `api_client.[resource]._[method]`.
26+
- Do **not** define a function inside another function, for example:
27+
```python
28+
def outer_function(self):
29+
def inner_function():
30+
# do something
31+
inner_function()
32+
```
33+
- Do **not** import libraries inside a function:
34+
```python
35+
def function(self):
36+
import some_library
37+
# do something
38+
```
39+
40+
## Integration Test Template
41+
42+
Use this template when writing a new integration test.
43+
44+
### Shared Fixture Template
45+
```python
46+
@pytest.fixture(scope="module or class")
47+
def shared_fixture():
48+
"""
49+
Shared fixture for test cases.
50+
"""
51+
# 1. Prepare the environment and data
52+
code, data = api_client.sss.xxx()
53+
54+
# 2. Assert the result
55+
assert code == xxxx, f"Expected status code xxxx, got {code} with data: {data}"
56+
57+
output = {
58+
"key1": "value1",
59+
"key2": "value2",
60+
}
61+
62+
yield output
63+
64+
# 3. Teardown if needed
65+
api_client.sss.teardown_method()
66+
```
67+
68+
### Test Case Template
69+
```python
70+
@pytest.mark.p0
71+
@pytest.mark.skip_version_if("???", reason="???")
72+
class TestXXXX:
73+
"""
74+
Test description.
75+
"""
76+
77+
@pytest.mark.p0
78+
def test_xxxx(self, ${some fixtures and shared_fixture}):
79+
"""
80+
Test description.
81+
"""
82+
# 1. Prepare the environment and data
83+
shared_data = shared_fixture
84+
85+
# 2. Call the API
86+
code, data = api_client.sss.xxx()
87+
88+
# 3. Assert the result
89+
assert code == xxxx, f"Expected status code xxxx, got {code} with data: {data}"
90+
```
91+
92+
## Harvester API Manager Template
93+
94+
Use this structure when implementing a new Harvester API manager.
95+
96+
```python
97+
import base64
98+
from .base import BaseManager, DEFAULT_NAMESPACE
99+
100+
101+
class XxxsManager(BaseManager):
102+
PATH_fmt = "/api/v1/namespaces/{ns}/xxx/{name}"
103+
CREATE_fmt = "v1/harvester/xxx"
104+
105+
def create_data(self, name, namespace, data, annotations=None):
106+
return {
107+
"type": "xxx",
108+
"metadata": {
109+
"namespace": namespace,
110+
"name": name,
111+
"annotations": annotations,
112+
},
113+
}
114+
115+
def create(self, name, data, namespace=DEFAULT_NAMESPACE, annotations=None, **kwargs):
116+
data = self.create_data(name, namespace, data, annotations=annotations)
117+
return self._create(self.CREATE_fmt, json=data, **kwargs)
118+
119+
def get(self, name, namespace=DEFAULT_NAMESPACE, *, raw=False):
120+
return self._get(self.PATH_fmt.format(ns=namespace, name=name), raw=raw)
121+
122+
def delete(self, name, namespace=DEFAULT_NAMESPACE, *, raw=False):
123+
return self._delete(self.PATH_fmt.format(ns=namespace, name=name), raw=raw)
124+
```

0 commit comments

Comments
 (0)