Skip to content
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
ed1af69
HadesArtemisAdapter init
paoxin Jan 26, 2026
123ecce
modify HadesLogManager to post logs to HadesArtemisAdapter
paoxin Jan 26, 2026
6b76ced
add jobID to global env, add adapter.go init
paoxin Feb 2, 2026
d186714
add adapter logic + send to artemis endpoint
paoxin Feb 2, 2026
f8cee80
use slog.Error, change ports back
paoxin Feb 4, 2026
fbe1c44
edit adapter sendToArtemis endpoint
paoxin Feb 10, 2026
6af0e66
send only execution logs instead
paoxin Feb 12, 2026
0a2120b
adapt adapter to new ResultDTO
paoxin Feb 15, 2026
d41c8f4
update .env.example, rabbit comments
paoxin Feb 16, 2026
57b87eb
rabiit comments
paoxin Feb 16, 2026
ed8e2f1
go mod tidy, add docstrings
paoxin Feb 16, 2026
e999aea
add comments
paoxin Feb 16, 2026
3c3323c
rabbit
paoxin Feb 16, 2026
614a46c
rabbit
paoxin Feb 16, 2026
2f67a70
Merge remote-tracking branch 'origin/main' into feat/hades-artemis-ad…
paoxin Feb 16, 2026
105983a
add Dockerfiles, update docker compose files, update build.yml
paoxin Feb 16, 2026
d166bf8
fix build.yml
paoxin Feb 16, 2026
655d3e8
fix compose files
paoxin Feb 16, 2026
b198e38
go mod tidy
paoxin Feb 16, 2026
da9d373
aggregate and send logs when build fails too
paoxin Feb 23, 2026
13ca7ec
update docstrings
paoxin Feb 23, 2026
1724e50
rabbit
paoxin Feb 23, 2026
bdda573
rename env var, move ContinueOnError to Step struct
paoxin Mar 9, 2026
0793d4c
Merge remote-tracking branch 'origin/main' into feat/hades-artemis-ad…
paoxin Mar 9, 2026
045d70b
update ci.yml
paoxin Mar 9, 2026
d9029e1
move adapter to seperate repo
paoxin Mar 9, 2026
f0161c3
rollback readme
paoxin Mar 9, 2026
b9e5c88
edit adapter endpoint config in docker compose
paoxin Mar 9, 2026
3a70a3d
go mod tidy
paoxin Mar 9, 2026
1d6427d
adapt traefik values to #388
paoxin Mar 13, 2026
ecfcd3f
Merge branch 'main' into feat/hades-artemis-adapter
paoxin Apr 30, 2026
d8d39dc
Merge branch 'main' into feat/hades-artemis-adapter
paoxin May 5, 2026
66d7416
Merge branch 'main' into feat/hades-artemis-adapter
paoxin Jun 2, 2026
01758aa
chore: deploy hadesLogManager in test environment
paoxin Jun 5, 2026
11d8b96
* fix duplicate traefik job
paoxin Jun 5, 2026
43f940b
update shared module reference to include SendJobLogs
paoxin Jun 5, 2026
a0a53d2
esolve shared module via replace directive for Docker build
paoxin Jun 5, 2026
dc57113
fix: use correct env var name for adapter URL in AggregatorConfig
paoxin Jun 5, 2026
85ee41d
inject JOB_NAME (participationId) into step container environment
paoxin Jun 5, 2026
dcfc29d
Support continueOnError for Kubernetes BuildJob steps
paoxin Jul 4, 2026
2ed83a3
async log sends, docker continueOnError, adapter env var
paoxin Jul 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@ WATCH_NAMESPACE="hades"
DELETE_ON_COMPLETE="true"
MAX_PARALLELISM="100"

### HadesArtemisAdapter Options ###
ARTEMIS_ADAPTER_PORT=8082 # Port for the Artemis Adapter to listen on (default: 8082)
Comment thread
paoxin marked this conversation as resolved.
Outdated
ARTEMIS_BASE_URL=http://localhost:8080
ARTEMIS_NEW_RESULT_ENDPOINT=api/programming/public/programming-exercises/new-result
ARTEMIS_AUTH_TOKEN=superduperlongtestingsecrettoken

### HadesLogManager Options ###
API_ENDPOINT="http://localhost:8082/adapter/logs"

### DockerScheduler Options ###
DOCKER_HOST="unix:///var/run/docker.sock" # Docker host to connect to (default: unix:///var/run/docker.sock)
DOCKER_SCRIPT_EXECUTOR="/bin/bash -c" # Path to the script executor to use (default: /bin/sh)
Expand Down
164 changes: 164 additions & 0 deletions HadesArtemisAdapter/artemis_adapter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
package main
Comment thread
paoxin marked this conversation as resolved.
Outdated

import (
"bytes"
"context"
"encoding/json"
"fmt"
"log/slog"
"net/http"
"sync"
"time"

"github.com/ls1intum/hades/shared/buildlogs"
)

type ArtemisAdapter struct {
logs sync.Map // jobID (string) -> []buildlogs.LogEntry (only Step 2:execution logs)
results sync.Map // jobID (string) -> results
jobLocks sync.Map // jobID (string) -> *sync.Mutex
httpClient *http.Client
cfg AdapterConfig
}

// Result DTOs used by Artemis
type ResultMetadata struct {
JobName string `json:"jobName"`
UUID string `json:"uuid"`
AssignmentRepoBranchName string `json:"assignmentRepoBranchName"`
IsBuildSuccessful bool `json:"isBuildSuccessful"`
AssignmentRepoCommitHash string `json:"assignmentRepoCommitHash"`
TestsRepoCommitHash string `json:"testsRepoCommitHash"`
BuildCompletionTime string `json:"buildCompletionTime"`
Passed int `json:"passed"`
}

type TestSuiteDTO struct {
Name string `json:"name"`
Time float64 `json:"time"`
Errors int `json:"errors"`
Skipped int `json:"skipped"`
Failures int `json:"failures"`
Tests int `json:"tests"`
TestCases []TestCaseDTO `json:"testCases"`
}

type TestCaseDTO struct {
Name string `json:"name"`
Classname string `json:"classname"`
Time float64 `json:"time"`
Failures []TestCaseDetailMessageDTO `json:"failures"` // empty for passing tests
Errors []TestCaseDetailMessageDTO `json:"errors"` // empty for passing tests
Successes []TestCaseDetailMessageDTO `json:"successInfos"` // empty for failing tests
}

type TestCaseDetailMessageDTO struct {
Message string `json:"message"`
Type string `json:"type"`
MessageWithStackTrace string `json:"messageWithStackTrace"`
}

type ResultDTO struct {
ResultMetadata
Results []TestSuiteDTO `json:"results"`
BuildLogs []buildlogs.LogEntry `json:"logs"`
}

const requestTimeout = 10 * time.Second

func NewAdapter(ctx context.Context, cfg AdapterConfig) *ArtemisAdapter {
aa := ArtemisAdapter{
httpClient: &http.Client{Timeout: requestTimeout},
cfg: cfg,
}

return &aa
}

// StoreLogs only stores Step 2 (execution) logs for a job ID and checks if results are ready
func (aa *ArtemisAdapter) StoreLogs(jobID string, logs []buildlogs.Log) error {
executionLogs := []buildlogs.LogEntry{}
if len(logs) < 2 {
slog.Error("Execution logs missing", "jobID", jobID)
executionLogs = []buildlogs.LogEntry{}
} else {
executionLogs = logs[1].Logs
}

aa.logs.Store(jobID, executionLogs)
return aa.checkAndSendIfReady(jobID)
}
Comment thread
paoxin marked this conversation as resolved.
Outdated

// StoreResults stores results for a job ID and checks if logs are ready
func (aa *ArtemisAdapter) StoreResults(jobID string, results ResultDTO) error {
aa.results.Store(jobID, results)
slog.Debug("Stored results", "jobID", jobID, "results", results.Results)
return aa.checkAndSendIfReady(jobID)
}

// checkAndSendIfReady checks if both logs and results exist for a jobID
// If both are present, combines them and sends to Artemis
func (aa *ArtemisAdapter) checkAndSendIfReady(jobID string) error {
// Get or create mutex for this specific job
lockVal, _ := aa.jobLocks.LoadOrStore(jobID, &sync.Mutex{})
lock := lockVal.(*sync.Mutex)

lock.Lock()
defer lock.Unlock()

logs, logsExist := aa.logs.Load(jobID)
results, resultsExist := aa.results.Load(jobID)

// If both logs and results exist, combine and send
if logsExist && resultsExist {
logs := logs.([]buildlogs.LogEntry)
results := results.(ResultDTO)

results.BuildLogs = logs
slog.Debug("Combined logs and results", "jobID", jobID)

// Send to Artemis
if err := aa.sendToArtemis(results); err != nil {
slog.Error("Failed to send results with logs to Artemis", "jobID", jobID, "error", err)
return err
}
slog.Info("Successfully sent results with logs to Artemis", "jobID", jobID)

// Clean up after successful send
aa.logs.Delete(jobID)
aa.results.Delete(jobID)
aa.jobLocks.Delete(jobID)
} else {
slog.Debug("Waiting for complete data", "jobID", jobID, "hasLogs", logsExist, "hasResults", resultsExist)
}

return nil
}
Comment thread
paoxin marked this conversation as resolved.
Outdated

// sendToArtemis sends the combined result DTO to the Artemis endpoint
func (aa *ArtemisAdapter) sendToArtemis(dto ResultDTO) error {
endpoint := fmt.Sprintf("%s/%s/%s", aa.cfg.ArtemisBaseURL, aa.cfg.NewResultEndpoint, dto.JobName)

jsonData, err := json.Marshal(dto)
if err != nil {
return fmt.Errorf("marshaling DTO to JSON: %w", err)
}

req, err := http.NewRequest("POST", endpoint, bytes.NewBuffer(jsonData))
if err != nil {
return fmt.Errorf("creating request: %w", err)
}

req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", aa.cfg.ArtemisAuthToken)

resp, err := aa.httpClient.Do(req)
if err != nil {
return fmt.Errorf("sending request to Artemis: %w", err)
}
defer resp.Body.Close()

slog.Info("Request sent", "status", resp.Status)

return nil
}
49 changes: 49 additions & 0 deletions HadesArtemisAdapter/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
module HadesArtemisAdapter

go 1.25.3

require (
github.com/gin-gonic/gin v1.11.0
github.com/ls1intum/hades/shared v0.0.0-20260116114842-b44546727e4b
)

require (
github.com/bytedance/sonic v1.14.0 // indirect
github.com/bytedance/sonic/loader v0.3.0 // indirect
github.com/caarlos0/env/v11 v11.3.1 // indirect
github.com/cloudwego/base64x v0.1.6 // indirect
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
github.com/gin-contrib/sse v1.1.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.27.0 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/goccy/go-yaml v1.18.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/joho/godotenv v1.5.1 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.18.0 // indirect
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/nats-io/nats.go v1.48.0 // indirect
github.com/nats-io/nkeys v0.4.11 // indirect
github.com/nats-io/nuid v1.0.1 // indirect
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
github.com/quic-go/qpack v0.5.1 // indirect
github.com/quic-go/quic-go v0.54.0 // indirect
Comment thread
paoxin marked this conversation as resolved.
Outdated
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.3.0 // indirect
go.uber.org/mock v0.5.0 // indirect
golang.org/x/arch v0.20.0 // indirect
golang.org/x/crypto v0.45.0 // indirect
golang.org/x/mod v0.29.0 // indirect
golang.org/x/net v0.47.0 // indirect
golang.org/x/sync v0.18.0 // indirect
golang.org/x/sys v0.38.0 // indirect
golang.org/x/text v0.31.0 // indirect
golang.org/x/tools v0.38.0 // indirect
google.golang.org/protobuf v1.36.9 // indirect
)
106 changes: 106 additions & 0 deletions HadesArtemisAdapter/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
github.com/bytedance/sonic v1.14.0 h1:/OfKt8HFw0kh2rj8N0F6C/qPGRESq0BbaNZgcNXXzQQ=
github.com/bytedance/sonic v1.14.0/go.mod h1:WoEbx8WTcFJfzCe0hbmyTGrfjt8PzNEBdxlNUO24NhA=
github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA=
github.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI=
github.com/caarlos0/env/v11 v11.3.1 h1:cArPWC15hWmEt+gWk7YBi7lEXTXCvpaSdCiZE2X5mCA=
github.com/caarlos0/env/v11 v11.3.1/go.mod h1:qupehSf/Y0TUTsxKywqRt/vJjN5nz6vauiYEUUr8P4U=
github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M=
github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w=
github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM=
github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk=
github.com/gin-gonic/gin v1.11.0/go.mod h1:+iq/FyxlGzII0KHiBGjuNn4UNENUlKbGlNmc+W50Dls=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4=
github.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo=
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw=
github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=
github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/ls1intum/hades/shared v0.0.0-20260116114842-b44546727e4b h1:qr4I+vH9qvuUIDMNyhcovwSapdd1AAbVjr2D8M1rlbw=
github.com/ls1intum/hades/shared v0.0.0-20260116114842-b44546727e4b/go.mod h1:dtZoDaLxyhyNlMNGZ/zHJ2pEwvVcv62uPZD4f4y1jKY=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/nats-io/nats.go v1.48.0 h1:pSFyXApG+yWU/TgbKCjmm5K4wrHu86231/w84qRVR+U=
github.com/nats-io/nats.go v1.48.0/go.mod h1:iRWIPokVIFbVijxuMQq4y9ttaBTMe0SFdlZfMDd+33g=
github.com/nats-io/nkeys v0.4.11 h1:q44qGV008kYd9W1b1nEBkNzvnWxtRSQ7A8BoqRrcfa0=
github.com/nats-io/nkeys v0.4.11/go.mod h1:szDimtgmfOi9n25JpfIdGw12tZFYXqhGxjhVxsatHVE=
github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
github.com/quic-go/quic-go v0.54.0 h1:6s1YB9QotYI6Ospeiguknbp2Znb/jZYjZLRXn9kMQBg=
github.com/quic-go/quic-go v0.54.0/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQEm+l8zTY=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA=
github.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4=
go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
golang.org/x/arch v0.20.0 h1:dx1zTU0MAE98U+TQ8BLl7XsJbgze2WnNKF/8tGp/Q6c=
golang.org/x/arch v0.20.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk=
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ=
golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs=
google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw=
google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Loading