diracx-db 0.0.1a22__tar.gz → 0.0.1a23__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/PKG-INFO +1 -1
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/src/diracx/db/sql/job_logging/db.py +20 -16
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/src/diracx/db/sql/utils/job.py +1 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/src/diracx_db.egg-info/PKG-INFO +1 -1
- diracx_db-0.0.1a23/tests/jobs/test_jobLoggingDB.py +80 -0
- diracx_db-0.0.1a22/tests/jobs/test_jobLoggingDB.py +0 -41
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/README.md +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/pyproject.toml +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/setup.cfg +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/src/diracx/db/__init__.py +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/src/diracx/db/__main__.py +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/src/diracx/db/exceptions.py +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/src/diracx/db/os/__init__.py +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/src/diracx/db/os/job_parameters.py +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/src/diracx/db/os/utils.py +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/src/diracx/db/py.typed +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/src/diracx/db/sql/__init__.py +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/src/diracx/db/sql/auth/__init__.py +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/src/diracx/db/sql/auth/db.py +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/src/diracx/db/sql/auth/schema.py +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/src/diracx/db/sql/dummy/__init__.py +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/src/diracx/db/sql/dummy/db.py +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/src/diracx/db/sql/dummy/schema.py +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/src/diracx/db/sql/job/__init__.py +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/src/diracx/db/sql/job/db.py +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/src/diracx/db/sql/job/schema.py +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/src/diracx/db/sql/job_logging/__init__.py +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/src/diracx/db/sql/job_logging/schema.py +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/src/diracx/db/sql/pilot_agents/__init__.py +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/src/diracx/db/sql/pilot_agents/db.py +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/src/diracx/db/sql/pilot_agents/schema.py +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/src/diracx/db/sql/sandbox_metadata/__init__.py +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/src/diracx/db/sql/sandbox_metadata/db.py +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/src/diracx/db/sql/sandbox_metadata/schema.py +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/src/diracx/db/sql/task_queue/__init__.py +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/src/diracx/db/sql/task_queue/db.py +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/src/diracx/db/sql/task_queue/schema.py +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/src/diracx/db/sql/utils/__init__.py +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/src/diracx_db.egg-info/SOURCES.txt +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/src/diracx_db.egg-info/dependency_links.txt +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/src/diracx_db.egg-info/entry_points.txt +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/src/diracx_db.egg-info/requires.txt +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/src/diracx_db.egg-info/top_level.txt +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/tests/auth/test_authorization_flow.py +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/tests/auth/test_device_flow.py +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/tests/auth/test_refresh_token.py +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/tests/jobs/test_jobDB.py +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/tests/jobs/test_sandbox_metadata.py +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/tests/opensearch/test_connection.py +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/tests/opensearch/test_index_template.py +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/tests/opensearch/test_search.py +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/tests/pilot_agents/__init__.py +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/tests/pilot_agents/test_pilotAgentsDB.py +0 -0
- {diracx_db-0.0.1a22 → diracx_db-0.0.1a23}/tests/test_dummyDB.py +0 -0
@@ -105,10 +105,9 @@ class JobLoggingDB(BaseSQLDB):
|
|
105
105
|
|
106
106
|
seqnum = {jid: seqnum for jid, seqnum in (await self.conn.execute(seqnum_stmt))}
|
107
107
|
# IF a seqnum is not found, then assume it does not exist and the first sequence number is 1.
|
108
|
-
|
109
108
|
# https://docs.sqlalchemy.org/en/20/orm/queryguide/dml.html#orm-bulk-insert-statements
|
110
109
|
await self.conn.execute(
|
111
|
-
insert(
|
110
|
+
LoggingInfo.__table__.insert(),
|
112
111
|
[
|
113
112
|
{
|
114
113
|
"JobID": record.job_id,
|
@@ -118,38 +117,43 @@ class JobLoggingDB(BaseSQLDB):
|
|
118
117
|
"ApplicationStatus": record.application_status[:255],
|
119
118
|
"StatusTime": record.date,
|
120
119
|
"StatusTimeOrder": get_epoc(record.date),
|
121
|
-
"
|
120
|
+
"StatusSource": record.source[:32],
|
122
121
|
}
|
123
122
|
for record in records
|
124
123
|
],
|
125
124
|
)
|
126
125
|
|
127
|
-
async def get_records(self,
|
126
|
+
async def get_records(self, job_ids: list[int]) -> dict[int, JobStatusReturn]:
|
128
127
|
"""Returns a Status,MinorStatus,ApplicationStatus,StatusTime,Source tuple
|
129
128
|
for each record found for job specified by its jobID in historical order.
|
130
129
|
"""
|
130
|
+
# We could potentially use a group_by here, but we need to post-process the
|
131
|
+
# results later.
|
131
132
|
stmt = (
|
132
133
|
select(
|
134
|
+
LoggingInfo.JobID,
|
133
135
|
LoggingInfo.Status,
|
134
136
|
LoggingInfo.MinorStatus,
|
135
137
|
LoggingInfo.ApplicationStatus,
|
136
138
|
LoggingInfo.StatusTime,
|
137
139
|
LoggingInfo.Source,
|
138
140
|
)
|
139
|
-
.where(LoggingInfo.JobID
|
141
|
+
.where(LoggingInfo.JobID.in_(job_ids))
|
140
142
|
.order_by(LoggingInfo.StatusTimeOrder, LoggingInfo.StatusTime)
|
141
143
|
)
|
142
144
|
rows = await self.conn.execute(stmt)
|
143
145
|
|
144
|
-
values =
|
146
|
+
values = defaultdict(list)
|
145
147
|
for (
|
148
|
+
job_id,
|
146
149
|
status,
|
147
150
|
minor_status,
|
148
151
|
application_status,
|
149
152
|
status_time,
|
150
153
|
status_source,
|
151
154
|
) in rows:
|
152
|
-
|
155
|
+
|
156
|
+
values[job_id].append(
|
153
157
|
[
|
154
158
|
status,
|
155
159
|
minor_status,
|
@@ -161,16 +165,16 @@ class JobLoggingDB(BaseSQLDB):
|
|
161
165
|
|
162
166
|
# If no value has been set for the application status in the first place,
|
163
167
|
# We put this status to unknown
|
164
|
-
res =
|
165
|
-
|
166
|
-
if
|
167
|
-
|
168
|
+
res: dict = defaultdict(list)
|
169
|
+
for job_id, history in values.items():
|
170
|
+
if history[0][2] == "idem":
|
171
|
+
history[0][2] = "Unknown"
|
168
172
|
|
169
173
|
# We replace "idem" values by the value previously stated
|
170
|
-
for i in range(1, len(
|
174
|
+
for i in range(1, len(history)):
|
171
175
|
for j in range(3):
|
172
|
-
if
|
173
|
-
|
176
|
+
if history[i][j] == "idem":
|
177
|
+
history[i][j] = history[i - 1][j]
|
174
178
|
|
175
179
|
# And we replace arrays with tuples
|
176
180
|
for (
|
@@ -179,8 +183,8 @@ class JobLoggingDB(BaseSQLDB):
|
|
179
183
|
application_status,
|
180
184
|
status_time,
|
181
185
|
status_source,
|
182
|
-
) in
|
183
|
-
res.append(
|
186
|
+
) in history:
|
187
|
+
res[job_id].append(
|
184
188
|
JobStatusReturn(
|
185
189
|
Status=status,
|
186
190
|
MinorStatus=minor_status,
|
@@ -0,0 +1,80 @@
|
|
1
|
+
from datetime import datetime, timezone
|
2
|
+
|
3
|
+
import pytest
|
4
|
+
|
5
|
+
from diracx.core.models import JobStatus
|
6
|
+
from diracx.db.sql import JobLoggingDB
|
7
|
+
|
8
|
+
|
9
|
+
@pytest.fixture
|
10
|
+
async def job_logging_db():
|
11
|
+
job_logging_db = JobLoggingDB("sqlite+aiosqlite:///:memory:")
|
12
|
+
async with job_logging_db.engine_context():
|
13
|
+
async with job_logging_db.engine.begin() as conn:
|
14
|
+
await conn.run_sync(job_logging_db.metadata.create_all)
|
15
|
+
yield job_logging_db
|
16
|
+
|
17
|
+
|
18
|
+
async def test_insert_records(job_logging_db: JobLoggingDB):
|
19
|
+
async with job_logging_db as job_logging_db:
|
20
|
+
# Arrange
|
21
|
+
date = datetime.now(timezone.utc)
|
22
|
+
|
23
|
+
# Act
|
24
|
+
for i in range(50):
|
25
|
+
await job_logging_db.insert_record(
|
26
|
+
i,
|
27
|
+
status=JobStatus.RECEIVED,
|
28
|
+
minor_status="received_minor_status",
|
29
|
+
application_status="application_status",
|
30
|
+
date=date,
|
31
|
+
source="pytest",
|
32
|
+
)
|
33
|
+
await job_logging_db.insert_record(
|
34
|
+
i,
|
35
|
+
status=JobStatus.SUBMITTING,
|
36
|
+
minor_status="submitted_minor_status",
|
37
|
+
application_status="application_status",
|
38
|
+
date=date,
|
39
|
+
source="pytest",
|
40
|
+
)
|
41
|
+
await job_logging_db.insert_record(
|
42
|
+
i,
|
43
|
+
status=JobStatus.RUNNING,
|
44
|
+
minor_status="running_minor_status",
|
45
|
+
application_status="application_status",
|
46
|
+
date=date,
|
47
|
+
source="pytest",
|
48
|
+
)
|
49
|
+
|
50
|
+
# Assert
|
51
|
+
res = await job_logging_db.get_records([i for i in range(50)])
|
52
|
+
|
53
|
+
assert len(res) == 50
|
54
|
+
# Check the first job - first record
|
55
|
+
assert res[0][0].Status == JobStatus.RECEIVED.value
|
56
|
+
assert res[0][0].MinorStatus == "received_minor_status"
|
57
|
+
assert res[0][0].ApplicationStatus == "application_status"
|
58
|
+
assert res[0][0].StatusTime == date
|
59
|
+
assert res[0][0].Source == "pytest"
|
60
|
+
|
61
|
+
# Check the first job - second record
|
62
|
+
assert res[0][1].Status == JobStatus.SUBMITTING.value
|
63
|
+
assert res[0][1].MinorStatus == "submitted_minor_status"
|
64
|
+
assert res[0][1].ApplicationStatus == "application_status"
|
65
|
+
assert res[0][1].StatusTime == date
|
66
|
+
assert res[0][1].Source == "pytest"
|
67
|
+
|
68
|
+
# Check the first job - third record
|
69
|
+
assert res[0][2].Status == JobStatus.RUNNING.value
|
70
|
+
assert res[0][2].MinorStatus == "running_minor_status"
|
71
|
+
assert res[0][2].ApplicationStatus == "application_status"
|
72
|
+
assert res[0][2].StatusTime == date
|
73
|
+
assert res[0][2].Source == "pytest"
|
74
|
+
|
75
|
+
# Check the last job - third record
|
76
|
+
assert res[49][2].Status == JobStatus.RUNNING.value
|
77
|
+
assert res[49][2].MinorStatus == "running_minor_status"
|
78
|
+
assert res[49][2].ApplicationStatus == "application_status"
|
79
|
+
assert res[49][2].StatusTime == date
|
80
|
+
assert res[49][2].Source == "pytest"
|
@@ -1,41 +0,0 @@
|
|
1
|
-
from datetime import datetime, timezone
|
2
|
-
|
3
|
-
import pytest
|
4
|
-
|
5
|
-
from diracx.core.models import JobStatus
|
6
|
-
from diracx.db.sql import JobLoggingDB
|
7
|
-
|
8
|
-
|
9
|
-
@pytest.fixture
|
10
|
-
async def job_logging_db():
|
11
|
-
job_logging_db = JobLoggingDB("sqlite+aiosqlite:///:memory:")
|
12
|
-
async with job_logging_db.engine_context():
|
13
|
-
async with job_logging_db.engine.begin() as conn:
|
14
|
-
await conn.run_sync(job_logging_db.metadata.create_all)
|
15
|
-
yield job_logging_db
|
16
|
-
|
17
|
-
|
18
|
-
async def test_insert_record(job_logging_db: JobLoggingDB):
|
19
|
-
async with job_logging_db as job_logging_db:
|
20
|
-
# Arrange
|
21
|
-
date = datetime.now(timezone.utc)
|
22
|
-
|
23
|
-
# Act
|
24
|
-
await job_logging_db.insert_record(
|
25
|
-
1,
|
26
|
-
status=JobStatus.RECEIVED,
|
27
|
-
minor_status="minor_status",
|
28
|
-
application_status="application_status",
|
29
|
-
date=date,
|
30
|
-
source="pytest",
|
31
|
-
)
|
32
|
-
|
33
|
-
# Assert
|
34
|
-
res = await job_logging_db.get_records(1)
|
35
|
-
|
36
|
-
assert len(res) == 1
|
37
|
-
assert res[0].Status == JobStatus.RECEIVED.value
|
38
|
-
assert res[0].MinorStatus == "minor_status"
|
39
|
-
assert res[0].ApplicationStatus == "application_status"
|
40
|
-
assert res[0].StatusTime == date
|
41
|
-
assert res[0].Source == "pytest"
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|