- test.md: 25 endpoint tests (13 GET + 12 POST) all PASS, including Kafka flow - troubleshoot.md: 9 real problems faced during deployment with fixes - Updated mkdocs.yml nav to include new pages Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
15 KiB
Test Results — Scheduler Service
Namespace: sagarpatil-4844
Base URL: https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService
Database: os_scheduling_db on mysql-8-0
Date: 2026-03-20
Seed Data
Data seeded from testconfig/mysql/data.sql:
- 15 status_types (SUBMITTED, RUNNING, COMPLETED, FAILED, etc.)
- 1 cluster: "Cluster 1" (id=1)
- 1 group: "os-group-1" (id=1)
- 1 job_type: "Default" for os-group-1
- 1 job_detail, 1 schedule, 1 job, 2 job_triggers, 1 job_stat
- 1 command_prefix_image_mapping, 1 container_image_version_tag, 1 tag
GET Endpoint Tests
1. GET /cluster?id=1
curl 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/cluster?id=1'
Response:
{
"clusters": [
{
"id": 1,
"name": "Cluster 1",
"description": "Test Cluster 1",
"status": 1,
"createdAt": 1742428200000,
"updatedAt": 1742428200000
}
],
"status": "OK"
}
Result: PASS
2. GET /cluster?name=Cluster 1
curl 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/cluster?name=Cluster%201'
Response:
{
"clusters": [
{
"id": 1,
"name": "Cluster 1",
"description": "Test Cluster 1",
"status": 1
}
],
"status": "OK"
}
Result: PASS
3. GET /group?id=1
curl 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/group?id=1'
Response:
{
"groupDetails": [
{
"id": 1,
"groupName": "os-group-1",
"clusterId": 1,
"status": 1,
"maxParallelJobs": 10,
"createdAt": 1742428200000,
"updatedAt": 1742428200000
}
],
"status": "OK"
}
Result: PASS
4. GET /group?groupName=os-group-1
curl 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/group?groupName=os-group-1'
Response:
{
"groupDetails": [
{
"id": 1,
"groupName": "os-group-1",
"clusterId": 1,
"status": 1,
"maxParallelJobs": 10
}
],
"status": "OK"
}
Result: PASS
5. GET /jobTrigger?id=1
curl 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/jobTrigger?id=1'
Response:
{
"jobTriggers": [
{
"id": 1,
"jobName": "TestJob",
"groupName": "os-group-1",
"applicationName": "TestApp",
"status": "SUBMITTED",
"clusterId": 1,
"createdAt": 1742428200000,
"updatedAt": 1742428200000
}
],
"status": "OK"
}
Result: PASS
6. GET /jobTrigger?jobName=TestJob
curl 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/jobTrigger?jobName=TestJob'
Response:
{
"jobTriggers": [
{
"id": 1,
"jobName": "TestJob",
"groupName": "os-group-1",
"applicationName": "TestApp",
"status": "SUBMITTED"
}
],
"status": "OK"
}
Result: PASS
7. GET /schedules?id=1
curl 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/schedules?id=1'
Response:
{
"schedules": [
{
"id": 1,
"name": "DefaultTestSchedule",
"groupName": "os-group-1",
"cronExpression": "0 0/5 * * * ?",
"status": 1,
"createdAt": 1742428200000,
"updatedAt": 1742428200000
}
],
"status": "OK"
}
Result: PASS
8. GET /jobDetail?jobDetailId=1
curl 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/jobDetail?jobDetailId=1'
Response:
{
"jobDetails": [
{
"jobDetailId": 1,
"command": "echo hello",
"priority": 1,
"retryCount": 3,
"retryPeriod": 60,
"timeout": 3600,
"status": 1
}
],
"status": "OK"
}
Result: PASS
9. GET /jobType?groupName=os-group-1&name=Default
curl 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/jobType?groupName=os-group-1&name=Default'
Response:
{
"jobTypes": [
{
"id": 1,
"name": "Default",
"groupName": "os-group-1",
"containerImage": "default-image",
"status": 1
}
],
"status": "OK"
}
Result: PASS
10. GET /tags?id=1&groupId=1
curl 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/tags?id=1&groupId=1'
Response:
{
"tags": [
{
"id": 1,
"name": "testTag",
"groupId": 1,
"status": 1
}
],
"status": "OK"
}
Result: PASS
11. GET /commandPrefixImageMapping?command=python&groupName=os-group-1
curl 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/commandPrefixImageMapping?command=python&groupName=os-group-1'
Response:
{
"commandPrefixImageMappings": [
{
"id": 1,
"command": "python",
"groupName": "os-group-1",
"containerImage": "python:3.9",
"status": 1
}
],
"status": "OK"
}
Result: PASS
12. GET /containerImageVersionTag?containerImage=container-image-1
curl 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/containerImageVersionTag?containerImage=container-image-1'
Response:
{
"containerImageVersionTags": [
{
"id": 1,
"containerImage": "container-image-1",
"versionTag": "v1.0",
"status": 1
}
],
"status": "OK"
}
Result: PASS
13. GET /schedulesMetadata?scheduleId=1&groupId=1
curl 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/schedulesMetadata?scheduleId=1&groupId=1'
Response:
{
"schedulesMetadata": [
{
"id": 1,
"scheduleId": 1,
"groupId": 1,
"key": "testKey",
"value": "testValue",
"status": 1
}
],
"status": "OK"
}
Result: PASS
POST Endpoint Tests
14. POST /group
curl -X POST 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/group' \
-H 'Content-Type: application/json' \
-d '{
"groupDetail": {
"groupName": "os-group-2",
"clusterId": 1,
"status": 1,
"maxParallelJobs": 5
}
}'
Response:
{
"status": "OK",
"groupDetail": {
"id": 2,
"groupName": "os-group-2",
"clusterId": 1,
"status": 1,
"maxParallelJobs": 5
}
}
Result: PASS
15. POST /schedules
curl -X POST 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/schedules' \
-H 'Content-Type: application/json' \
-d '{
"schedule": {
"name": "NewTestSchedule",
"groupName": "os-group-1",
"cronExpression": "0 0/10 * * * ?",
"status": 1
}
}'
Response:
{
"status": "OK",
"schedule": {
"id": 2,
"name": "NewTestSchedule",
"groupName": "os-group-1",
"cronExpression": "0 0/10 * * * ?",
"status": 1
}
}
Result: PASS
16. POST /jobTrigger
curl -X POST 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/jobTrigger' \
-H 'Content-Type: application/json' \
-d '{
"jobTrigger": {
"id": 1,
"status": "SUBMITTED"
}
}'
Response:
{
"status": "OK",
"jobTrigger": {
"id": 1,
"status": "SUBMITTED"
}
}
Result: PASS
17. POST /jobStat
curl -X POST 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/jobStat' \
-H 'Content-Type: application/json' \
-d '{
"jobStat": {
"jobName": "TestJob",
"groupName": "os-group-1",
"applicationName": "TestApp",
"status": "COMPLETED",
"startTime": 1742428200000,
"endTime": 1742431800000
}
}'
Response:
{
"status": "OK",
"jobStat": {
"id": 2,
"jobName": "TestJob",
"groupName": "os-group-1",
"status": "COMPLETED"
}
}
Result: PASS
18. POST /tags
curl -X POST 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/tags' \
-H 'Content-Type: application/json' \
-d '{
"tag": {
"name": "newTag",
"groupId": 1,
"status": 1
}
}'
Response:
{
"status": "OK",
"tag": {
"id": 2,
"name": "newTag",
"groupId": 1,
"status": 1
}
}
Result: PASS
19. POST /containerImageVersionTag
curl -X POST 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/containerImageVersionTag' \
-H 'Content-Type: application/json' \
-d '{
"containerImageVersionTag": {
"containerImage": "container-image-2",
"versionTag": "v2.0",
"status": 1
}
}'
Response:
{
"status": "OK",
"containerImageVersionTag": {
"id": 2,
"containerImage": "container-image-2",
"versionTag": "v2.0",
"status": 1
}
}
Result: PASS
20. POST /schedulesMetadata
curl -X POST 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/schedulesMetadata' \
-H 'Content-Type: application/json' \
-d '{
"schedulesMetadata": {
"scheduleId": 1,
"groupId": 1,
"key": "newKey",
"value": "newValue",
"status": 1
}
}'
Response:
{
"status": "OK",
"schedulesMetadata": {
"id": 2,
"scheduleId": 1,
"groupId": 1,
"key": "newKey",
"value": "newValue",
"status": 1
}
}
Result: PASS
21. POST /commandPrefixImageMapping
curl -X POST 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/commandPrefixImageMapping' \
-H 'Content-Type: application/json' \
-d '{
"commandPrefixImageMapping": {
"command": "java",
"groupName": "os-group-1",
"containerImage": "openjdk:11",
"status": 1
}
}'
Response:
{
"status": "OK",
"commandPrefixImageMapping": {
"id": 2,
"command": "java",
"groupName": "os-group-1",
"containerImage": "openjdk:11",
"status": 1
}
}
Result: PASS
22. POST /jobType
curl -X POST 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/jobType' \
-H 'Content-Type: application/json' \
-d '{
"jobType": {
"name": "CustomType",
"groupName": "os-group-1",
"containerImage": "custom-image:latest",
"monitoringTags": "{\"FAILED_JOBS\": \"sev4\"}",
"status": 1
}
}'
Response:
{
"status": "OK",
"jobType": {
"id": 2,
"name": "CustomType",
"groupName": "os-group-1",
"containerImage": "custom-image:latest",
"monitoringTags": "{\"FAILED_JOBS\": \"sev4\"}",
"status": 1
}
}
Result: PASS
Note:
monitoringTagsmust be a JSON string (escaped), not a raw JSON object.
23. POST /jobDetail
curl -X POST 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/jobDetail' \
-H 'Content-Type: application/json' \
-d '{
"jobDetail": {
"jobDetailId": 1,
"priority": 2,
"retryPeriod": 120
}
}'
Response:
{
"status": "OK",
"jobDetail": {
"jobDetailId": 1,
"priority": 2,
"retryPeriod": 120
}
}
Result: PASS
24. POST /job (useArgoWorkflows: false)
curl -X POST 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/job' \
-H 'Content-Type: application/json' \
-H 'os-scheduling-group: os-group-1' \
-d '{
"job": {
"jobName": "testJob1",
"applicationName": "testApp1",
"command": "echo hello",
"jobTypeName": "Default",
"useArgoWorkflows": false
}
}'
Response:
{
"status": "OK",
"job": {
"jobId": 3,
"jobName": "testJob1",
"applicationName": "testApp1",
"status": "SUBMITTED"
}
}
Result: PASS
Creates 3 DB entries:
job_details,jobs,job_triggers. No Kafka event published.
25. POST /job (useArgoWorkflows: true) — Kafka Flow
curl -X POST 'https://scheduler-service-sagarpatil-4844.os-tf-qa.onlinesales.ai/schedulerService/job' \
-H 'Content-Type: application/json' \
-H 'os-scheduling-group: os-group-1' \
-d '{
"job": {
"jobName": "argoJob1",
"applicationName": "testApp1",
"command": "echo argo",
"jobTypeName": "Default",
"useArgoWorkflows": true
}
}'
Response:
{
"status": "OK",
"job": {
"jobId": 6,
"jobName": "argoJob1",
"applicationName": "testApp1",
"status": "SUBMITTED"
}
}
Scheduler Logs (confirmed):
ArgoEventSender: Sending event for job 6 | eventType: argo_ondemand_cluster_1 | eventName: ARGO_JOB_SUBMISSION
ArgoEventSender: Successfully posted event for job: 6
Result: PASS
Full flow:
POST /job→ArgoEventSender→EventManager→ Kafka (GCP_KAFKA) RequiresPROD_KAFKA_TOPIC_VERSION_SETTINGin property-settings DB.
POST-Only Endpoints (No GET)
| Endpoint | GET | POST | Reason |
|---|---|---|---|
/job |
Not supported (500) | PASS | initServletObjectMap(null, JobPostRequest.class, ...) |
/jobStat |
Not supported (500) | PASS | initServletObjectMap(null, JobStatPostRequest.class, ...) |
Summary
Test Results
| # | Endpoint | Method | Result |
|---|---|---|---|
| 1 | /cluster?id=1 | GET | PASS |
| 2 | /cluster?name=Cluster 1 | GET | PASS |
| 3 | /group?id=1 | GET | PASS |
| 4 | /group?groupName=os-group-1 | GET | PASS |
| 5 | /jobTrigger?id=1 | GET | PASS |
| 6 | /jobTrigger?jobName=TestJob | GET | PASS |
| 7 | /schedules?id=1 | GET | PASS |
| 8 | /jobDetail?jobDetailId=1 | GET | PASS |
| 9 | /jobType?groupName=...&name=... | GET | PASS |
| 10 | /tags?id=1&groupId=1 | GET | PASS |
| 11 | /commandPrefixImageMapping | GET | PASS |
| 12 | /containerImageVersionTag | GET | PASS |
| 13 | /schedulesMetadata | GET | PASS |
| 14 | /group | POST | PASS |
| 15 | /schedules | POST | PASS |
| 16 | /jobTrigger | POST | PASS |
| 17 | /jobStat | POST | PASS |
| 18 | /tags | POST | PASS |
| 19 | /containerImageVersionTag | POST | PASS |
| 20 | /schedulesMetadata | POST | PASS |
| 21 | /commandPrefixImageMapping | POST | PASS |
| 22 | /jobType | POST | PASS |
| 23 | /jobDetail | POST | PASS |
| 24 | /job (useArgoWorkflows: false) | POST | PASS |
| 25 | /job (useArgoWorkflows: true) | POST | PASS |
Total: 25/25 PASS
Key Findings
- 13 GET endpoints all working with correct query parameters
- 9 POST endpoints all working with correct JSON body format
- 2 POST-only endpoints (
/job,/jobStat) — GET returns 500 by design - Kafka flow verified —
useArgoWorkflows: truepublishes events via EventManager to Kafka - Event type:
argo_ondemand_cluster_1, Event name:ARGO_JOB_SUBMISSION - Application:
osOnDemandJobsArgoRunner
Dependencies Verified
| Dependency | Status | Notes |
|---|---|---|
| MySQL (os_scheduling_db) | Working | Via Hibernate XML, no Hades needed |
| Event-Manager-V2 | Working | Receives Argo events from scheduler |
| Property-Settings-V2 | Working | Provides PROD_KAFKA_TOPIC_VERSION_SETTING |
| Kafka | Working | Receives events via GCP_KAFKA path |
| Hades | Not needed | Scheduler uses direct Hibernate connection |