waldur-site-agent-cscs-dwdi 0.7.0__tar.gz → 0.7.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of waldur-site-agent-cscs-dwdi might be problematic. Click here for more details.

@@ -0,0 +1,284 @@
1
+ Metadata-Version: 2.4
2
+ Name: waldur-site-agent-cscs-dwdi
3
+ Version: 0.7.3
4
+ Summary: CSCS-DWDI reporting plugin for Waldur Site Agent
5
+ Author-email: OpenNode Team <info@opennodecloud.com>
6
+ Requires-Python: <4,>=3.9
7
+ Requires-Dist: httpx>=0.25.0
8
+ Requires-Dist: waldur-site-agent>=0.7.0
9
+ Description-Content-Type: text/markdown
10
+
11
+ # CSCS-DWDI Plugin for Waldur Site Agent
12
+
13
+ This plugin provides integration with the CSCS Data Warehouse Data Intelligence (DWDI) system to report both
14
+ computational and storage usage data to Waldur.
15
+
16
+ ## Overview
17
+
18
+ The plugin implements two separate backends to handle different types of accounting data:
19
+
20
+ - **Compute Backend** (`cscs-dwdi-compute`): Reports CPU and node hour usage from HPC clusters
21
+ - **Storage Backend** (`cscs-dwdi-storage`): Reports storage space and inode usage from filesystems
22
+
23
+ ## Backend Types
24
+
25
+ ### Compute Backend
26
+
27
+ The compute backend queries the DWDI API for computational resource usage and reports:
28
+
29
+ - Node hours consumed by accounts and users
30
+ - CPU hours consumed by accounts and users
31
+ - Account-level and user-level usage aggregation
32
+
33
+ **API Endpoints Used:**
34
+
35
+ - `/api/v1/compute/usage-month/account` - Monthly usage data
36
+ - `/api/v1/compute/usage-day/account` - Daily usage data
37
+
38
+ ### Storage Backend
39
+
40
+ The storage backend queries the DWDI API for storage resource usage and reports:
41
+
42
+ - Storage space used (converted from bytes to configured units)
43
+ - Inode (file count) usage
44
+ - Path-based resource identification
45
+
46
+ **API Endpoints Used:**
47
+
48
+ - `/api/v1/storage/usage-month/filesystem_name/data_type` - Monthly storage usage
49
+ - `/api/v1/storage/usage-day/filesystem_name/data_type` - Daily storage usage
50
+
51
+ ## Configuration
52
+
53
+ ### Compute Backend Configuration
54
+
55
+ ```yaml
56
+ backend_type: "cscs-dwdi-compute"
57
+
58
+ backend_settings:
59
+ cscs_dwdi_api_url: "https://dwdi.cscs.ch"
60
+ cscs_dwdi_client_id: "your_oidc_client_id"
61
+ cscs_dwdi_client_secret: "your_oidc_client_secret"
62
+ cscs_dwdi_oidc_token_url: "https://auth.cscs.ch/realms/cscs/protocol/openid-connect/token"
63
+ cscs_dwdi_oidc_scope: "openid" # Optional
64
+
65
+ backend_components:
66
+ nodeHours:
67
+ measured_unit: "node-hours"
68
+ unit_factor: 1
69
+ accounting_type: "usage"
70
+ label: "Node Hours"
71
+
72
+ cpuHours:
73
+ measured_unit: "cpu-hours"
74
+ unit_factor: 1
75
+ accounting_type: "usage"
76
+ label: "CPU Hours"
77
+ ```
78
+
79
+ ### Storage Backend Configuration
80
+
81
+ ```yaml
82
+ backend_type: "cscs-dwdi-storage"
83
+
84
+ backend_settings:
85
+ cscs_dwdi_api_url: "https://dwdi.cscs.ch"
86
+ cscs_dwdi_client_id: "your_oidc_client_id"
87
+ cscs_dwdi_client_secret: "your_oidc_client_secret"
88
+ cscs_dwdi_oidc_token_url: "https://auth.cscs.ch/realms/cscs/protocol/openid-connect/token"
89
+
90
+ # Storage-specific settings
91
+ storage_filesystem: "lustre"
92
+ storage_data_type: "projects"
93
+ storage_tenant: "cscs" # Optional
94
+
95
+ # Map Waldur resource IDs to storage paths
96
+ storage_path_mapping:
97
+ "project_123": "/store/projects/proj123"
98
+ "project_456": "/store/projects/proj456"
99
+
100
+ backend_components:
101
+ storage_space:
102
+ measured_unit: "GB"
103
+ unit_factor: 0.000000001 # Convert bytes to GB
104
+ accounting_type: "usage"
105
+ label: "Storage Space (GB)"
106
+
107
+ storage_inodes:
108
+ measured_unit: "count"
109
+ unit_factor: 1
110
+ accounting_type: "usage"
111
+ label: "File Count"
112
+ ```
113
+
114
+ ## Authentication
115
+
116
+ Both backends use OIDC client credentials flow for authentication with the DWDI API. You need:
117
+
118
+ - `cscs_dwdi_client_id`: OIDC client identifier
119
+ - `cscs_dwdi_client_secret`: OIDC client secret
120
+ - `cscs_dwdi_oidc_token_url`: OIDC token endpoint URL
121
+ - `cscs_dwdi_oidc_scope`: OIDC scope (optional, defaults to "openid")
122
+
123
+ ## SOCKS Proxy Support
124
+
125
+ Both backends support SOCKS proxy for network connectivity. This is useful when the DWDI API is only accessible
126
+ through a proxy or jump host.
127
+
128
+ ### SOCKS Proxy Configuration
129
+
130
+ Add the SOCKS proxy setting to your backend configuration:
131
+
132
+ ```yaml
133
+ backend_settings:
134
+ # ... other settings ...
135
+ socks_proxy: "socks5://localhost:12345" # SOCKS5 proxy URL
136
+ ```
137
+
138
+ ### Supported Proxy Types
139
+
140
+ - **SOCKS5**: `socks5://hostname:port`
141
+ - **SOCKS4**: `socks4://hostname:port`
142
+ - **HTTP**: `http://hostname:port`
143
+
144
+ ### Usage Examples
145
+
146
+ **SSH Tunnel with SOCKS5:**
147
+
148
+ ```bash
149
+ # Create SSH tunnel to jump host
150
+ ssh -D 12345 -N user@jumphost.cscs.ch
151
+
152
+ # Configure backend to use tunnel
153
+ backend_settings:
154
+ socks_proxy: "socks5://localhost:12345"
155
+ ```
156
+
157
+ **HTTP Proxy:**
158
+
159
+ ```yaml
160
+ backend_settings:
161
+ socks_proxy: "http://proxy.cscs.ch:8080"
162
+ ```
163
+
164
+ ## Resource Identification
165
+
166
+ ### Compute Resources
167
+
168
+ For compute resources, the system uses account names as returned by the DWDI API. The Waldur resource
169
+ `backend_id` should match the account name in the cluster accounting system.
170
+
171
+ ### Storage Resources
172
+
173
+ For storage resources, there are two options:
174
+
175
+ 1. **Direct Path Usage**: Set the Waldur resource `backend_id` to the actual filesystem path
176
+ 2. **Path Mapping**: Use the `storage_path_mapping` setting to map resource IDs to paths
177
+
178
+ ## Usage Reporting
179
+
180
+ Both backends are read-only and designed for usage reporting. They implement the `_get_usage_report()` method
181
+ but do not support:
182
+
183
+ - Account creation/deletion
184
+ - Resource management
185
+ - User management
186
+ - Limit setting
187
+
188
+ ## Example Configurations
189
+
190
+ See the `examples/` directory for complete configuration examples:
191
+
192
+ - `cscs-dwdi-compute-config.yaml` - Compute backend only
193
+ - `cscs-dwdi-storage-config.yaml` - Storage backend only
194
+ - `cscs-dwdi-combined-config.yaml` - Both backends in one configuration
195
+
196
+ ## Installation
197
+
198
+ The plugin is automatically discovered when the waldur-site-agent-cscs-dwdi package is installed alongside waldur-site-agent.
199
+
200
+ ```bash
201
+ # Install all workspace packages including cscs-dwdi plugin
202
+ uv sync --all-packages
203
+ ```
204
+
205
+ ## Testing
206
+
207
+ Run the test suite:
208
+
209
+ ```bash
210
+ uv run pytest plugins/cscs-dwdi/tests/
211
+ ```
212
+
213
+ ## API Compatibility
214
+
215
+ This plugin is compatible with DWDI API version 1 (`/api/v1/`). It requires the following API endpoints to be available:
216
+
217
+ **Compute API:**
218
+
219
+ - `/api/v1/compute/usage-month/account`
220
+ - `/api/v1/compute/usage-day/account`
221
+
222
+ **Storage API:**
223
+
224
+ - `/api/v1/storage/usage-month/filesystem_name/data_type`
225
+ - `/api/v1/storage/usage-day/filesystem_name/data_type`
226
+
227
+ ## Troubleshooting
228
+
229
+ ### Authentication Issues
230
+
231
+ - Verify OIDC client credentials are correct
232
+ - Check that the token endpoint URL is accessible
233
+ - Ensure the client has appropriate scopes
234
+
235
+ ### Storage Backend Issues
236
+
237
+ - Verify `storage_filesystem` and `storage_data_type` match available values in DWDI
238
+ - Check `storage_path_mapping` if using custom resource IDs
239
+ - Ensure storage paths exist in the DWDI system
240
+
241
+ ### Connection Issues
242
+
243
+ - Use the `ping()` method to test API connectivity
244
+ - Check network connectivity to the DWDI API endpoint
245
+ - Verify SSL/TLS configuration
246
+ - If behind a firewall, configure SOCKS proxy (`socks_proxy` setting)
247
+
248
+ ### Proxy Issues
249
+
250
+ - Verify proxy server is running and accessible
251
+ - Check proxy authentication if required
252
+ - Test proxy connectivity manually: `curl --proxy socks5://localhost:12345 https://dwdi.cscs.ch`
253
+ - Ensure proxy supports the required protocol (SOCKS4/5, HTTP)
254
+
255
+ ## Development
256
+
257
+ ### Project Structure
258
+
259
+ ```text
260
+ plugins/cscs-dwdi/
261
+ ├── pyproject.toml # Plugin configuration
262
+ ├── README.md # This documentation
263
+ ├── examples/ # Configuration examples
264
+ ├── waldur_site_agent_cscs_dwdi/
265
+ │ ├── __init__.py # Package init
266
+ │ ├── backend.py # Backend implementations
267
+ │ └── client.py # CSCS-DWDI API client
268
+ └── tests/
269
+ └── test_cscs_dwdi.py # Plugin tests
270
+ ```
271
+
272
+ ### Key Classes
273
+
274
+ - **`CSCSDWDIComputeBackend`**: Compute usage reporting backend
275
+ - **`CSCSDWDIStorageBackend`**: Storage usage reporting backend
276
+ - **`CSCSDWDIClient`**: HTTP client for CSCS-DWDI API communication
277
+
278
+ ### Extension Points
279
+
280
+ To extend the plugin:
281
+
282
+ 1. **Additional Endpoints**: Modify `CSCSDWDIClient` to support more API endpoints
283
+ 2. **Authentication Methods**: Update authentication logic in `client.py`
284
+ 3. **Data Processing**: Enhance response processing methods for additional data formats
@@ -0,0 +1,274 @@
1
+ # CSCS-DWDI Plugin for Waldur Site Agent
2
+
3
+ This plugin provides integration with the CSCS Data Warehouse Data Intelligence (DWDI) system to report both
4
+ computational and storage usage data to Waldur.
5
+
6
+ ## Overview
7
+
8
+ The plugin implements two separate backends to handle different types of accounting data:
9
+
10
+ - **Compute Backend** (`cscs-dwdi-compute`): Reports CPU and node hour usage from HPC clusters
11
+ - **Storage Backend** (`cscs-dwdi-storage`): Reports storage space and inode usage from filesystems
12
+
13
+ ## Backend Types
14
+
15
+ ### Compute Backend
16
+
17
+ The compute backend queries the DWDI API for computational resource usage and reports:
18
+
19
+ - Node hours consumed by accounts and users
20
+ - CPU hours consumed by accounts and users
21
+ - Account-level and user-level usage aggregation
22
+
23
+ **API Endpoints Used:**
24
+
25
+ - `/api/v1/compute/usage-month/account` - Monthly usage data
26
+ - `/api/v1/compute/usage-day/account` - Daily usage data
27
+
28
+ ### Storage Backend
29
+
30
+ The storage backend queries the DWDI API for storage resource usage and reports:
31
+
32
+ - Storage space used (converted from bytes to configured units)
33
+ - Inode (file count) usage
34
+ - Path-based resource identification
35
+
36
+ **API Endpoints Used:**
37
+
38
+ - `/api/v1/storage/usage-month/filesystem_name/data_type` - Monthly storage usage
39
+ - `/api/v1/storage/usage-day/filesystem_name/data_type` - Daily storage usage
40
+
41
+ ## Configuration
42
+
43
+ ### Compute Backend Configuration
44
+
45
+ ```yaml
46
+ backend_type: "cscs-dwdi-compute"
47
+
48
+ backend_settings:
49
+ cscs_dwdi_api_url: "https://dwdi.cscs.ch"
50
+ cscs_dwdi_client_id: "your_oidc_client_id"
51
+ cscs_dwdi_client_secret: "your_oidc_client_secret"
52
+ cscs_dwdi_oidc_token_url: "https://auth.cscs.ch/realms/cscs/protocol/openid-connect/token"
53
+ cscs_dwdi_oidc_scope: "openid" # Optional
54
+
55
+ backend_components:
56
+ nodeHours:
57
+ measured_unit: "node-hours"
58
+ unit_factor: 1
59
+ accounting_type: "usage"
60
+ label: "Node Hours"
61
+
62
+ cpuHours:
63
+ measured_unit: "cpu-hours"
64
+ unit_factor: 1
65
+ accounting_type: "usage"
66
+ label: "CPU Hours"
67
+ ```
68
+
69
+ ### Storage Backend Configuration
70
+
71
+ ```yaml
72
+ backend_type: "cscs-dwdi-storage"
73
+
74
+ backend_settings:
75
+ cscs_dwdi_api_url: "https://dwdi.cscs.ch"
76
+ cscs_dwdi_client_id: "your_oidc_client_id"
77
+ cscs_dwdi_client_secret: "your_oidc_client_secret"
78
+ cscs_dwdi_oidc_token_url: "https://auth.cscs.ch/realms/cscs/protocol/openid-connect/token"
79
+
80
+ # Storage-specific settings
81
+ storage_filesystem: "lustre"
82
+ storage_data_type: "projects"
83
+ storage_tenant: "cscs" # Optional
84
+
85
+ # Map Waldur resource IDs to storage paths
86
+ storage_path_mapping:
87
+ "project_123": "/store/projects/proj123"
88
+ "project_456": "/store/projects/proj456"
89
+
90
+ backend_components:
91
+ storage_space:
92
+ measured_unit: "GB"
93
+ unit_factor: 0.000000001 # Convert bytes to GB
94
+ accounting_type: "usage"
95
+ label: "Storage Space (GB)"
96
+
97
+ storage_inodes:
98
+ measured_unit: "count"
99
+ unit_factor: 1
100
+ accounting_type: "usage"
101
+ label: "File Count"
102
+ ```
103
+
104
+ ## Authentication
105
+
106
+ Both backends use OIDC client credentials flow for authentication with the DWDI API. You need:
107
+
108
+ - `cscs_dwdi_client_id`: OIDC client identifier
109
+ - `cscs_dwdi_client_secret`: OIDC client secret
110
+ - `cscs_dwdi_oidc_token_url`: OIDC token endpoint URL
111
+ - `cscs_dwdi_oidc_scope`: OIDC scope (optional, defaults to "openid")
112
+
113
+ ## SOCKS Proxy Support
114
+
115
+ Both backends support SOCKS proxy for network connectivity. This is useful when the DWDI API is only accessible
116
+ through a proxy or jump host.
117
+
118
+ ### SOCKS Proxy Configuration
119
+
120
+ Add the SOCKS proxy setting to your backend configuration:
121
+
122
+ ```yaml
123
+ backend_settings:
124
+ # ... other settings ...
125
+ socks_proxy: "socks5://localhost:12345" # SOCKS5 proxy URL
126
+ ```
127
+
128
+ ### Supported Proxy Types
129
+
130
+ - **SOCKS5**: `socks5://hostname:port`
131
+ - **SOCKS4**: `socks4://hostname:port`
132
+ - **HTTP**: `http://hostname:port`
133
+
134
+ ### Usage Examples
135
+
136
+ **SSH Tunnel with SOCKS5:**
137
+
138
+ ```bash
139
+ # Create SSH tunnel to jump host
140
+ ssh -D 12345 -N user@jumphost.cscs.ch
141
+
142
+ # Configure backend to use tunnel
143
+ backend_settings:
144
+ socks_proxy: "socks5://localhost:12345"
145
+ ```
146
+
147
+ **HTTP Proxy:**
148
+
149
+ ```yaml
150
+ backend_settings:
151
+ socks_proxy: "http://proxy.cscs.ch:8080"
152
+ ```
153
+
154
+ ## Resource Identification
155
+
156
+ ### Compute Resources
157
+
158
+ For compute resources, the system uses account names as returned by the DWDI API. The Waldur resource
159
+ `backend_id` should match the account name in the cluster accounting system.
160
+
161
+ ### Storage Resources
162
+
163
+ For storage resources, there are two options:
164
+
165
+ 1. **Direct Path Usage**: Set the Waldur resource `backend_id` to the actual filesystem path
166
+ 2. **Path Mapping**: Use the `storage_path_mapping` setting to map resource IDs to paths
167
+
168
+ ## Usage Reporting
169
+
170
+ Both backends are read-only and designed for usage reporting. They implement the `_get_usage_report()` method
171
+ but do not support:
172
+
173
+ - Account creation/deletion
174
+ - Resource management
175
+ - User management
176
+ - Limit setting
177
+
178
+ ## Example Configurations
179
+
180
+ See the `examples/` directory for complete configuration examples:
181
+
182
+ - `cscs-dwdi-compute-config.yaml` - Compute backend only
183
+ - `cscs-dwdi-storage-config.yaml` - Storage backend only
184
+ - `cscs-dwdi-combined-config.yaml` - Both backends in one configuration
185
+
186
+ ## Installation
187
+
188
+ The plugin is automatically discovered when the waldur-site-agent-cscs-dwdi package is installed alongside waldur-site-agent.
189
+
190
+ ```bash
191
+ # Install all workspace packages including cscs-dwdi plugin
192
+ uv sync --all-packages
193
+ ```
194
+
195
+ ## Testing
196
+
197
+ Run the test suite:
198
+
199
+ ```bash
200
+ uv run pytest plugins/cscs-dwdi/tests/
201
+ ```
202
+
203
+ ## API Compatibility
204
+
205
+ This plugin is compatible with DWDI API version 1 (`/api/v1/`). It requires the following API endpoints to be available:
206
+
207
+ **Compute API:**
208
+
209
+ - `/api/v1/compute/usage-month/account`
210
+ - `/api/v1/compute/usage-day/account`
211
+
212
+ **Storage API:**
213
+
214
+ - `/api/v1/storage/usage-month/filesystem_name/data_type`
215
+ - `/api/v1/storage/usage-day/filesystem_name/data_type`
216
+
217
+ ## Troubleshooting
218
+
219
+ ### Authentication Issues
220
+
221
+ - Verify OIDC client credentials are correct
222
+ - Check that the token endpoint URL is accessible
223
+ - Ensure the client has appropriate scopes
224
+
225
+ ### Storage Backend Issues
226
+
227
+ - Verify `storage_filesystem` and `storage_data_type` match available values in DWDI
228
+ - Check `storage_path_mapping` if using custom resource IDs
229
+ - Ensure storage paths exist in the DWDI system
230
+
231
+ ### Connection Issues
232
+
233
+ - Use the `ping()` method to test API connectivity
234
+ - Check network connectivity to the DWDI API endpoint
235
+ - Verify SSL/TLS configuration
236
+ - If behind a firewall, configure SOCKS proxy (`socks_proxy` setting)
237
+
238
+ ### Proxy Issues
239
+
240
+ - Verify proxy server is running and accessible
241
+ - Check proxy authentication if required
242
+ - Test proxy connectivity manually: `curl --proxy socks5://localhost:12345 https://dwdi.cscs.ch`
243
+ - Ensure proxy supports the required protocol (SOCKS4/5, HTTP)
244
+
245
+ ## Development
246
+
247
+ ### Project Structure
248
+
249
+ ```text
250
+ plugins/cscs-dwdi/
251
+ ├── pyproject.toml # Plugin configuration
252
+ ├── README.md # This documentation
253
+ ├── examples/ # Configuration examples
254
+ ├── waldur_site_agent_cscs_dwdi/
255
+ │ ├── __init__.py # Package init
256
+ │ ├── backend.py # Backend implementations
257
+ │ └── client.py # CSCS-DWDI API client
258
+ └── tests/
259
+ └── test_cscs_dwdi.py # Plugin tests
260
+ ```
261
+
262
+ ### Key Classes
263
+
264
+ - **`CSCSDWDIComputeBackend`**: Compute usage reporting backend
265
+ - **`CSCSDWDIStorageBackend`**: Storage usage reporting backend
266
+ - **`CSCSDWDIClient`**: HTTP client for CSCS-DWDI API communication
267
+
268
+ ### Extension Points
269
+
270
+ To extend the plugin:
271
+
272
+ 1. **Additional Endpoints**: Modify `CSCSDWDIClient` to support more API endpoints
273
+ 2. **Authentication Methods**: Update authentication logic in `client.py`
274
+ 3. **Data Processing**: Enhance response processing methods for additional data formats
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "waldur-site-agent-cscs-dwdi"
3
- version = "0.7.0"
3
+ version = "0.7.3"
4
4
  description = "CSCS-DWDI reporting plugin for Waldur Site Agent"
5
5
  readme = "README.md"
6
6
  authors = [{ name = "OpenNode Team", email = "info@opennodecloud.com" }]
@@ -19,4 +19,5 @@ waldur-site-agent = { workspace = true }
19
19
 
20
20
  # Entry points for exporting backends
21
21
  [project.entry-points."waldur_site_agent.backends"]
22
- cscs-dwdi = "waldur_site_agent_cscs_dwdi.backend:CSCSDWDIBackend"
22
+ cscs-dwdi-compute = "waldur_site_agent_cscs_dwdi.backend:CSCSDWDIComputeBackend"
23
+ cscs-dwdi-storage = "waldur_site_agent_cscs_dwdi.backend:CSCSDWDIStorageBackend"
@@ -5,7 +5,7 @@ from typing import Any
5
5
  from unittest.mock import MagicMock, patch
6
6
 
7
7
  import pytest
8
- from waldur_site_agent_cscs_dwdi.backend import CSCSDWDIBackend
8
+ from waldur_site_agent_cscs_dwdi.backend import CSCSDWDIComputeBackend, CSCSDWDIStorageBackend
9
9
  from waldur_site_agent_cscs_dwdi.client import CSCSDWDIClient
10
10
 
11
11
 
@@ -25,6 +25,18 @@ class TestCSCSDWDIClient:
25
25
  assert client.client_secret == "test_secret"
26
26
  assert client.oidc_token_url is None
27
27
  assert client.oidc_scope == "openid"
28
+ assert client.socks_proxy is None
29
+
30
+ def test_client_initialization_with_proxy(self) -> None:
31
+ """Test client initializes with SOCKS proxy."""
32
+ client = CSCSDWDIClient(
33
+ api_url="https://api.example.com",
34
+ client_id="test_client",
35
+ client_secret="test_secret",
36
+ socks_proxy="socks5://localhost:12345",
37
+ )
38
+
39
+ assert client.socks_proxy == "socks5://localhost:12345"
28
40
 
29
41
  def test_client_strips_trailing_slash(self) -> None:
30
42
  """Test client strips trailing slash from API URL."""
@@ -230,8 +242,8 @@ class TestCSCSDWDIClient:
230
242
  assert token1 == token2
231
243
 
232
244
 
233
- class TestCSCSDWDIBackend:
234
- """Tests for CSCS-DWDI backend."""
245
+ class TestCSCSDWDIComputeBackend:
246
+ """Tests for CSCS-DWDI compute backend."""
235
247
 
236
248
  def test_backend_initialization(self) -> None:
237
249
  """Test backend initializes with correct configuration."""
@@ -250,12 +262,36 @@ class TestCSCSDWDIBackend:
250
262
  }
251
263
  }
252
264
 
253
- backend = CSCSDWDIBackend(backend_settings, backend_components)
265
+ backend = CSCSDWDIComputeBackend(backend_settings, backend_components)
254
266
 
255
267
  assert backend.api_url == "https://api.example.com"
256
268
  assert backend.client_id == "test_client"
257
269
  assert backend.client_secret == "test_secret"
258
270
  assert isinstance(backend.cscs_client, CSCSDWDIClient)
271
+ assert backend.socks_proxy is None
272
+
273
+ def test_backend_initialization_with_proxy(self) -> None:
274
+ """Test backend initializes with SOCKS proxy configuration."""
275
+ backend_settings = {
276
+ "cscs_dwdi_api_url": "https://api.example.com",
277
+ "cscs_dwdi_client_id": "test_client",
278
+ "cscs_dwdi_client_secret": "test_secret",
279
+ "cscs_dwdi_oidc_token_url": "https://oidc.example.com/token",
280
+ "socks_proxy": "socks5://localhost:12345",
281
+ }
282
+ backend_components = {
283
+ "nodeHours": {
284
+ "measured_unit": "node-hours",
285
+ "unit_factor": 1,
286
+ "accounting_type": "usage",
287
+ "label": "Node Hours",
288
+ }
289
+ }
290
+
291
+ backend = CSCSDWDIComputeBackend(backend_settings, backend_components)
292
+
293
+ assert backend.socks_proxy == "socks5://localhost:12345"
294
+ assert backend.cscs_client.socks_proxy == "socks5://localhost:12345"
259
295
 
260
296
  def test_backend_initialization_missing_config(self) -> None:
261
297
  """Test backend raises error when configuration is missing."""
@@ -266,7 +302,7 @@ class TestCSCSDWDIBackend:
266
302
  backend_components: dict[str, dict] = {}
267
303
 
268
304
  with pytest.raises(ValueError) as exc_info:
269
- CSCSDWDIBackend(backend_settings, backend_components)
305
+ CSCSDWDIComputeBackend(backend_settings, backend_components)
270
306
 
271
307
  assert "cscs_dwdi_oidc_token_url" in str(exc_info.value)
272
308
 
@@ -286,7 +322,7 @@ class TestCSCSDWDIBackend:
286
322
  "label": "Node Hours",
287
323
  }
288
324
  }
289
- backend = CSCSDWDIBackend(backend_settings, backend_components)
325
+ backend = CSCSDWDIComputeBackend(backend_settings, backend_components)
290
326
 
291
327
  # Sample API response
292
328
  api_response = {
@@ -347,7 +383,7 @@ class TestCSCSDWDIBackend:
347
383
  "label": "Node Hours",
348
384
  }
349
385
  }
350
- backend = CSCSDWDIBackend(backend_settings, backend_components)
386
+ backend = CSCSDWDIComputeBackend(backend_settings, backend_components)
351
387
 
352
388
  # API response with same user appearing multiple times
353
389
  api_response = {
@@ -416,7 +452,7 @@ class TestCSCSDWDIBackend:
416
452
  "label": "Node Hours",
417
453
  }
418
454
  }
419
- backend = CSCSDWDIBackend(backend_settings, backend_components)
455
+ backend = CSCSDWDIComputeBackend(backend_settings, backend_components)
420
456
 
421
457
  # Test the method
422
458
  result = backend._get_usage_report(["account1", "account2"])
@@ -448,7 +484,7 @@ class TestCSCSDWDIBackend:
448
484
  "label": "Node Hours",
449
485
  }
450
486
  }
451
- backend = CSCSDWDIBackend(backend_settings, backend_components)
487
+ backend = CSCSDWDIComputeBackend(backend_settings, backend_components)
452
488
 
453
489
  # Mock the client method
454
490
  with patch.object(backend.cscs_client, "get_usage_for_month") as mock_get:
@@ -496,7 +532,7 @@ class TestCSCSDWDIBackend:
496
532
  "label": "Node Hours",
497
533
  }
498
534
  }
499
- backend = CSCSDWDIBackend(backend_settings, backend_components)
535
+ backend = CSCSDWDIComputeBackend(backend_settings, backend_components)
500
536
 
501
537
  with pytest.raises(NotImplementedError):
502
538
  backend.create_account({})