Skip to content

Commit dd203a9

Browse files
committed
feat(models): implement Value class for configuration management
- Add Value class with local and remote storage support - Add comprehensive unit tests for Value class - Update development documentation: - Add code structure guide - Add testing guide - Update contributing guidelines - Update development tasks The Value class implementation follows ADR-004 and provides: - Dual storage support (local/remote) - Complete serialization - Robust validation - Comprehensive test coverage
1 parent 8b82f54 commit dd203a9

File tree

7 files changed

+623
-25
lines changed

7 files changed

+623
-25
lines changed

CONTRIBUTING.md

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,53 @@ We use GitHub to host code, to track issues and feature requests, as well as acc
1919
5. Make sure your code passes all code quality checks.
2020
6. Issue that pull request!
2121

22+
## Version Control Guidelines
23+
24+
### Branch Naming
25+
- Feature branches: `feature/short-description`
26+
- Bug fixes: `fix/issue-description`
27+
- Documentation: `docs/what-changed`
28+
- Release branches: `release/version-number`
29+
30+
### Commit Messages
31+
Follow the [Conventional Commits](https://www.conventionalcommits.org/) specification:
32+
```
33+
<type>[optional scope]: <description>
34+
35+
[optional body]
36+
37+
[optional footer(s)]
38+
```
39+
40+
Types:
41+
- `feat`: New feature
42+
- `fix`: Bug fix
43+
- `docs`: Documentation only changes
44+
- `style`: Changes that do not affect the meaning of the code
45+
- `refactor`: Code change that neither fixes a bug nor adds a feature
46+
- `test`: Adding missing tests or correcting existing tests
47+
- `chore`: Changes to the build process or auxiliary tools
48+
49+
Example:
50+
```
51+
feat(value): add support for remote storage backends
52+
53+
- Implement ValueBackend interface
54+
- Add AWS Secrets Manager backend
55+
- Add Azure Key Vault backend
56+
57+
Closes #123
58+
```
59+
60+
## Important Documentation
61+
62+
Before contributing, please review these important documents:
63+
64+
1. [Code Structure](docs/Development/code-structure.md) - Understanding the codebase organization
65+
2. [Testing Guide](docs/Development/testing.md) - Testing standards and practices
66+
3. [Architecture Overview](docs/Design/low-level-design.md) - System architecture and design decisions
67+
4. [ADRs](docs/ADRs/) - Architecture Decision Records
68+
2269
## Development Setup
2370

2471
1. Clone your fork:
@@ -86,12 +133,6 @@ tox -e py39 # For Python 3.9
86133
- Follow Google style for docstrings
87134
- Keep the README.md and other documentation up to date
88135

89-
### Documentation Requirements
90-
91-
- Use docstrings for all public modules, functions, classes, and methods
92-
- Follow Google style for docstrings
93-
- Keep the README.md and other documentation up to date
94-
95136
#### Required Extensions
96137

97138
When contributing to documentation, please note that we use the following extensions:
@@ -115,7 +156,7 @@ To preview Mermaid diagrams locally, you can:
115156

116157
## Any contributions you make will be under the MIT Software License
117158

118-
In short, when you submit code changes, your submissions are understood to be under the same [MIT License](LICENSE) that covers the project. Feel free to contact the maintainers if that's a concern.
159+
In short, when you submit code changes, your submissions are understood to be under the same [MIT License](./LICENSE) that covers the project. Feel free to contact the maintainers if that's a concern.
119160

120161
## Report bugs using GitHub's [issue tracker](https://github.com/zipstack/helm-values-manager/issues)
121162

@@ -135,4 +176,4 @@ We use GitHub issues to track public bugs. Report a bug by [opening a new issue]
135176

136177
## License
137178

138-
By contributing, you agree that your contributions will be licensed under its MIT License.
179+
By contributing, you agree that your contributions will be licensed under its [MIT License](./LICENSE).

docs/Development/code-structure.md

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# Code Structure
2+
3+
This document outlines the organization and structure of the Helm Values Manager codebase.
4+
5+
## Package Organization
6+
7+
```
8+
helm_values_manager/
9+
├── models/ # Core data models
10+
│ ├── __init__.py
11+
│ └── value.py # Value class for configuration management
12+
├── backends/ # Storage backend implementations
13+
│ ├── __init__.py
14+
│ ├── base.py # Abstract base class for backends
15+
│ ├── aws.py # AWS Secrets Manager backend
16+
│ └── azure.py # Azure Key Vault backend
17+
└── cli.py # CLI implementation
18+
```
19+
20+
## Core Components
21+
22+
### Models Package
23+
24+
The `models` package contains the core data structures used throughout the application.
25+
26+
#### Value Class
27+
The `Value` class is a fundamental component that handles configuration values:
28+
29+
```python
30+
class Value:
31+
"""
32+
Represents a configuration value with storage strategy.
33+
34+
Attributes:
35+
path (str): Configuration path (e.g., "app.replicas")
36+
environment (str): Environment name (e.g., "dev", "prod")
37+
storage_type (str): Type of storage ("local" or "remote")
38+
"""
39+
```
40+
41+
**Key Features:**
42+
- Dual storage support (local/remote)
43+
- Serialization capabilities
44+
- Input validation
45+
- Error handling
46+
47+
For implementation details, see the [Value Class Implementation Guide](value-class.md).
48+
49+
### Backends Package
50+
51+
The `backends` package provides storage implementations for different providers:
52+
53+
- `base.py`: Abstract base class defining the backend interface
54+
- `aws.py`: AWS Secrets Manager implementation
55+
- `azure.py`: Azure Key Vault implementation
56+
57+
Each backend must implement:
58+
```python
59+
class ValueBackend(ABC):
60+
@abstractmethod
61+
def get_value(self, key: str) -> str:
62+
"""Get a value from storage."""
63+
pass
64+
65+
@abstractmethod
66+
def set_value(self, key: str, value: str) -> None:
67+
"""Set a value in storage."""
68+
pass
69+
```
70+
71+
## Design Principles
72+
73+
1. **Clean Architecture**
74+
- Clear separation of concerns
75+
- Dependency inversion for backends
76+
- Model independence from storage
77+
78+
2. **Error Handling**
79+
- Custom exceptions for domain errors
80+
- Comprehensive error messages
81+
- Graceful error recovery
82+
83+
3. **Security**
84+
- Secure value storage
85+
- Input validation
86+
- No sensitive data logging
87+
88+
4. **Testing**
89+
- Unit tests for all components
90+
- Integration tests for backends
91+
- High code coverage requirement
92+
93+
## Further Reading
94+
95+
- [Architecture Overview](architecture.md)
96+
- [Testing Guide](testing.md)
97+
- [Security Guidelines](security.md)

docs/Development/tasks.md

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,23 @@
33
## Core Components
44

55
### Value Class Implementation
6-
- [ ] Create basic Value class structure
7-
- [ ] Add path, environment, storage_type, and backend attributes
8-
- [ ] Implement constructor with type hints
9-
- [ ] Add basic validation for attributes
10-
- [ ] Implement value resolution
11-
- [ ] Add get() method with local value support
12-
- [ ] Add set() method with local value support
13-
- [ ] Add remote value support in get() method
14-
- [ ] Add remote value support in set() method
15-
- [ ] Add serialization support
16-
- [ ] Implement to_dict() method
17-
- [ ] Implement from_dict() static method
18-
- [ ] Add tests for serialization/deserialization
19-
- [ ] Add value validation
20-
- [ ] Implement basic type validation
21-
- [ ] Add support for required field validation
22-
- [ ] Add support for sensitive field handling
6+
- [x] Create basic Value class structure
7+
- [x] Add path, environment, storage_type, and backend attributes
8+
- [x] Implement constructor with type hints
9+
- [x] Add basic validation for attributes
10+
- [x] Implement value resolution
11+
- [x] Add get() method with local value support
12+
- [x] Add set() method with local value support
13+
- [x] Add remote value support in get() method
14+
- [x] Add remote value support in set() method
15+
- [x] Add serialization support
16+
- [x] Implement to_dict() method
17+
- [x] Implement from_dict() static method
18+
- [x] Add tests for serialization/deserialization
19+
- [x] Add value validation
20+
- [x] Implement basic type validation
21+
- [x] Add support for required field validation
22+
- [x] Add support for sensitive field handling
2323

2424
### PathData Class Implementation
2525
- [ ] Create PathData class

docs/Development/testing.md

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
# Testing Guide
2+
3+
This document outlines the testing standards and practices for the Helm Values Manager project.
4+
5+
## Test Organization
6+
7+
```
8+
tests/
9+
├── unit/ # Unit tests
10+
│ ├── models/ # Tests for core models
11+
│ │ └── test_value.py
12+
│ └── backends/ # Tests for backend implementations
13+
├── integration/ # Integration tests
14+
│ └── backends/ # Backend integration tests
15+
└── conftest.py # Shared test fixtures
16+
```
17+
18+
## Test Categories
19+
20+
### Unit Tests
21+
22+
Unit tests focus on testing individual components in isolation. They should:
23+
- Test a single unit of functionality
24+
- Mock external dependencies
25+
- Be fast and independent
26+
- Cover both success and error cases
27+
28+
Example from `test_value.py`:
29+
```python
30+
def test_value_init_local():
31+
"""Test Value initialization with local storage."""
32+
value = Value(path="app.replicas", environment="dev")
33+
assert value.path == "app.replicas"
34+
assert value.environment == "dev"
35+
assert value.storage_type == "local"
36+
```
37+
38+
### Integration Tests
39+
40+
Integration tests verify component interactions, especially with external services:
41+
- Test actual backend implementations
42+
- Verify configuration loading
43+
- Test end-to-end workflows
44+
45+
## Testing Standards
46+
47+
### 1. Test Organization
48+
- Group related tests in classes
49+
- Use descriptive test names
50+
- Follow the file structure of the implementation
51+
- Keep test files focused and manageable
52+
53+
### 2. Test Coverage
54+
- Aim for 100% code coverage
55+
- Test all code paths
56+
- Include edge cases
57+
- Test error conditions
58+
59+
### 3. Test Quality
60+
- Follow Arrange-Act-Assert pattern
61+
- Keep tests independent
62+
- Use appropriate assertions
63+
- Write clear test descriptions
64+
65+
Example:
66+
```python
67+
def test_set_invalid_type():
68+
"""Test setting a non-string value."""
69+
value = Value(path="app.replicas", environment="dev")
70+
with pytest.raises(ValueError, match="Value must be a string"):
71+
value.set(3)
72+
```
73+
74+
### 4. Fixtures and Mocks
75+
- Use fixtures for common setup
76+
- Mock external dependencies
77+
- Keep mocks simple and focused
78+
- Use appropriate scoping
79+
80+
Example:
81+
```python
82+
@pytest.fixture
83+
def mock_backend():
84+
"""Create a mock backend for testing."""
85+
backend = Mock(spec=ValueBackend)
86+
backend.get_value.return_value = "mock_value"
87+
return backend
88+
```
89+
90+
## Running Tests
91+
92+
### Local Development
93+
```bash
94+
# Run all tests
95+
python -m pytest
96+
97+
# Run specific test file
98+
python -m pytest tests/unit/models/test_value.py
99+
100+
# Run with coverage
101+
python -m pytest --cov=helm_values_manager
102+
```
103+
104+
### Using Tox
105+
```bash
106+
# Run tests in all environments
107+
tox
108+
109+
# Run for specific Python version
110+
tox -e py39
111+
```
112+
113+
## Test Documentation
114+
115+
Each test should have:
116+
1. Clear docstring explaining purpose
117+
2. Well-structured setup and teardown
118+
3. Clear assertions with messages
119+
4. Proper error case handling
120+
121+
Example:
122+
```python
123+
def test_from_dict_missing_path():
124+
"""Test deserializing with missing path field."""
125+
data = {
126+
"environment": "dev",
127+
"storage_type": "local",
128+
"value": "3"
129+
}
130+
with pytest.raises(ValueError, match="Missing required field: path"):
131+
Value.from_dict(data)
132+
```
133+
134+
## Best Practices
135+
136+
1. **Test Independence**
137+
- Each test should run in isolation
138+
- Clean up after tests
139+
- Don't rely on test execution order
140+
141+
2. **Test Readability**
142+
- Use clear, descriptive names
143+
- Document test purpose
144+
- Keep tests simple and focused
145+
146+
3. **Test Maintenance**
147+
- Update tests when implementation changes
148+
- Remove obsolete tests
149+
- Keep test code as clean as production code
150+
151+
4. **Performance**
152+
- Keep unit tests fast
153+
- Use appropriate fixtures
154+
- Mock expensive operations
155+
156+
## Continuous Integration
157+
158+
Our CI pipeline:
159+
- Runs all tests
160+
- Checks code coverage
161+
- Enforces style guidelines
162+
- Runs security checks
163+
164+
## Further Reading
165+
166+
- [Code Structure](code-structure.md)
167+
- [Contributing Guide](../../CONTRIBUTING.md)
168+
- [Pre-commit Hooks](pre-commit-hooks.md)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
"""Models package for helm-values-manager."""
2+
3+
from .value import Value
4+
5+
__all__ = ["Value"]

0 commit comments

Comments
 (0)