Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,6 @@ vendor/github.com/prometheus/procfs/fixtures/26231/exe
/openshift-tests
/disruption
/update-tls-artifacts

.claude/*.local.json

2 changes: 2 additions & 0 deletions cmd/openshift-tests/openshift-tests.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/openshift/origin/pkg/cmd/openshift-tests/dev"
"github.com/openshift/origin/pkg/cmd/openshift-tests/disruption"
e2e_analysis "github.com/openshift/origin/pkg/cmd/openshift-tests/e2e-analysis"
"github.com/openshift/origin/pkg/cmd/openshift-tests/generate"
"github.com/openshift/origin/pkg/cmd/openshift-tests/images"
"github.com/openshift/origin/pkg/cmd/openshift-tests/list"
"github.com/openshift/origin/pkg/cmd/openshift-tests/monitor"
Expand Down Expand Up @@ -105,6 +106,7 @@ func main() {
timeline.NewTimelineCommand(ioStreams),
run_disruption.NewRunInClusterDisruptionMonitorCommand(ioStreams),
collectdiskcertificates.NewRunCollectDiskCertificatesCommand(ioStreams),
generate.NewGenerateCommand(ioStreams),
versioncmd.NewVersionCommand(ioStreams),
)

Expand Down
8 changes: 8 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/openshift/origin
go 1.24.0

require (
cloud.google.com/go/bigquery v1.69.0
cloud.google.com/go/storage v1.56.0
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.1
Expand Down Expand Up @@ -164,6 +165,7 @@ require (
github.com/ProtonMail/go-crypto v1.1.6 // indirect
github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b // indirect
github.com/antlr4-go/antlr/v4 v4.13.0 // indirect
github.com/apache/arrow/go/v15 v15.0.2 // indirect
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
github.com/armon/circbuf v0.0.0-20190214190532-5111143e8da2 // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
Expand Down Expand Up @@ -226,6 +228,7 @@ require (
github.com/go-playground/validator/v10 v10.26.0 // indirect
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
github.com/gocarina/gocsv v0.0.0-20231116093920-b87c2d0e983a // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/godbus/dbus/v5 v5.1.0 // indirect
github.com/gofrs/uuid v4.4.0+incompatible // indirect
github.com/gogo/protobuf v1.3.2 // indirect
Expand All @@ -235,6 +238,7 @@ require (
github.com/google/btree v1.1.3 // indirect
github.com/google/cadvisor v0.52.1 // indirect
github.com/google/cel-go v0.26.0 // indirect
github.com/google/flatbuffers v23.5.26+incompatible // indirect
github.com/google/gopacket v1.1.19 // indirect
github.com/google/goterm v0.0.0-20190703233501-fc88cf888a3f // indirect
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect
Expand Down Expand Up @@ -264,6 +268,7 @@ require (
github.com/karrick/godirwalk v1.17.0 // indirect
github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/klauspost/compress v1.18.0 // indirect
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/lestrrat-go/jspointer v0.0.0-20181205001929-82fadba7561c // indirect
Expand Down Expand Up @@ -315,6 +320,7 @@ require (
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/pelletier/go-toml v1.9.5 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/pierrec/lz4/v4 v4.1.18 // indirect
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
github.com/pkg/profile v1.7.0 // indirect
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
Expand Down Expand Up @@ -344,6 +350,7 @@ require (
github.com/xlab/treeprint v1.2.0 // indirect
github.com/zclconf/go-cty v1.16.2 // indirect
github.com/zeebo/errs v1.4.0 // indirect
github.com/zeebo/xxh3 v1.0.2 // indirect
go.etcd.io/bbolt v1.4.2 // indirect
go.etcd.io/etcd/pkg/v3 v3.6.4 // indirect
go.etcd.io/etcd/server/v3 v3.6.4 // indirect
Expand Down Expand Up @@ -375,6 +382,7 @@ require (
golang.org/x/text v0.29.0 // indirect
golang.org/x/time v0.12.0 // indirect
golang.org/x/tools v0.36.0 // indirect
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250818200422-3122310a409c // indirect
Expand Down
20 changes: 20 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,12 @@ cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvf
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
cloud.google.com/go/bigquery v1.69.0 h1:rZvHnjSUs5sHK3F9awiuFk2PeOaB8suqNuim21GbaTc=
cloud.google.com/go/bigquery v1.69.0/go.mod h1:TdGLquA3h/mGg+McX+GsqG9afAzTAcldMjqhdjHTLew=
cloud.google.com/go/compute/metadata v0.8.0 h1:HxMRIbao8w17ZX6wBnjhcDkW6lTFpgcaobyVfZWqRLA=
cloud.google.com/go/compute/metadata v0.8.0/go.mod h1:sYOGTp851OV9bOFJ9CH7elVvyzopvWQFNNghtDQ/Biw=
cloud.google.com/go/datacatalog v1.26.0 h1:eFgygb3DTufTWWUB8ARk+dSuXz+aefNJXTlkWlQcWwE=
cloud.google.com/go/datacatalog v1.26.0/go.mod h1:bLN2HLBAwB3kLTFT5ZKLHVPj/weNz6bR0c7nYp0LE14=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
Expand Down Expand Up @@ -203,6 +207,8 @@ github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYU
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI=
github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g=
github.com/apache/arrow/go/v15 v15.0.2 h1:60IliRbiyTWCWjERBCkO1W4Qun9svcYoZrSLcyOsMLE=
github.com/apache/arrow/go/v15 v15.0.2/go.mod h1:DGXsR3ajT524njufqf95822i+KTh+yea1jass9YXgjA=
github.com/apparentlymart/go-cidr v1.1.0 h1:2mAhrMoF+nhXqxTzSZMUzDHkLjmIHC+Zzn4tdgBZjnU=
github.com/apparentlymart/go-cidr v1.1.0/go.mod h1:EBcsNrHc3zQeuaeCeCtQruQm+n9/YjEn/vI25Lg7Gwc=
github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY=
Expand Down Expand Up @@ -434,6 +440,8 @@ github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6Wezm
github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY=
github.com/gocarina/gocsv v0.0.0-20231116093920-b87c2d0e983a h1:RYfmiM0zluBJOiPDJseKLEN4BapJ42uSi9SZBQ2YyiA=
github.com/gocarina/gocsv v0.0.0-20231116093920-b87c2d0e983a/go.mod h1:5YoVOkjYAQumqlV356Hj3xeYh4BdZuLE0/nRkf2NKkI=
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/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
Expand Down Expand Up @@ -495,6 +503,8 @@ github.com/google/cadvisor v0.52.1 h1:sC8SZ6jio9ds+P2dk51bgbeYeufxo55n0X3tmrpA9a
github.com/google/cadvisor v0.52.1/go.mod h1:OAhPcx1nOm5YwMh/JhpUOMKyv1YKLRtS9KgzWPndHmA=
github.com/google/cel-go v0.26.0 h1:DPGjXackMpJWH680oGY4lZhYjIameYmR+/6RBdDGmaI=
github.com/google/cel-go v0.26.0/go.mod h1:A9O8OU9rdvrK5MQyrqfIxo1a0u4g3sF8KB6PUIaryMM=
github.com/google/flatbuffers v23.5.26+incompatible h1:M9dgRyhJemaM4Sw8+66GHBu8ioaQmyPLg1b8VwK5WJg=
github.com/google/flatbuffers v23.5.26+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo=
github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
Expand Down Expand Up @@ -672,6 +682,8 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
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.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
Expand Down Expand Up @@ -900,6 +912,8 @@ github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3v
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/pierrec/lz4/v4 v4.1.18 h1:xaKrnTkyoqfh1YItXl56+6KJNVYWlEEPuAQW9xsplYQ=
github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4=
github.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A=
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
Expand Down Expand Up @@ -1047,8 +1061,12 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/zclconf/go-cty v1.16.2 h1:LAJSwc3v81IRBZyUVQDUdZ7hs3SYs9jv0eZJDWHD/70=
github.com/zclconf/go-cty v1.16.2/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE=
github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ=
github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
github.com/zeebo/errs v1.4.0 h1:XNdoD/RRMKP7HD0UhJnIzUy74ISdGGxURlYG8HSWSfM=
github.com/zeebo/errs v1.4.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4=
github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0=
github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA=
github.com/ziutek/telnet v0.0.0-20180329124119-c3b780dc415b/go.mod h1:IZpXDfkJ6tWD3PhBK5YzgQT+xJWh7OsdwiG8hA2MkO4=
go.etcd.io/bbolt v1.4.2 h1:IrUHp260R8c+zYx/Tm8QZr04CX+qWS5PGfPdevhdm1I=
go.etcd.io/bbolt v1.4.2/go.mod h1:Is8rSHO/b4f3XigBC0lL0+4FwAQv3HXEEIgFMuKHceM=
Expand Down Expand Up @@ -1417,6 +1435,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY=
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw=
gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
Expand Down
143 changes: 143 additions & 0 deletions pkg/cmd/openshift-tests/generate/durations/durations_command.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
package durations

import (
"context"
"encoding/json"
"fmt"
"os"
"strings"

"cloud.google.com/go/bigquery"
"github.com/spf13/cobra"
"google.golang.org/api/iterator"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/kubectl/pkg/util/templates"
)

func NewDurationsCommand(streams genericclioptions.IOStreams) *cobra.Command {
o := NewDurationsOptions(streams)

cmd := &cobra.Command{
Use: "durations",
Short: "Generate test duration data from BigQuery",
Long: templates.LongDesc(`
Generate test duration data from BigQuery

This command queries the BigQuery table containing junit test results and produces
a JSON file with average test durations for tests in the openshift-tests suite
from the last 7 days (configurable). Durations are calculated as the average
and rounded to the nearest second.

By default, the output is written to pkg/test/ginkgo/testDurations.json.

The output format is:
{
"test.name": {
"average_duration": 123
}
}
`),
SilenceUsage: true,
SilenceErrors: true,
RunE: func(cmd *cobra.Command, args []string) error {
if err := o.Complete(args); err != nil {
return err
}
if err := o.Validate(); err != nil {
return err
}
if err := o.Run(context.Background()); err != nil {
return err
}
return nil
},
}

o.AddFlags(cmd.Flags())
return cmd
}

// DurationResult represents a test duration result from BigQuery
type DurationResult struct {
TestName string `bigquery:"test_name"`
AverageDuration float64 `bigquery:"average_duration"`
}

// TestDurationData represents the output format for a single test
type TestDurationData struct {
AverageDuration int `json:"average_duration"`
}

// Run executes the durations command
func (o *DurationsOptions) Run(ctx context.Context) error {
// Create BigQuery client
client, err := bigquery.NewClient(ctx, o.ProjectID)
if err != nil {
return fmt.Errorf("failed to create BigQuery client: %w", err)
}
defer client.Close()

// Build the SQL query
query := o.buildQuery()

// Execute the query
q := client.Query(query)
it, err := q.Read(ctx)
if err != nil {
return fmt.Errorf("failed to execute query: %w", err)
}

// Collect results
results := make(map[string]TestDurationData)
for {
var row DurationResult
err := it.Next(&row)
if err == iterator.Done {
break
}
if err != nil {
return fmt.Errorf("failed to read query result: %w", err)
}

// Round to nearest second and store
results[row.TestName] = TestDurationData{
AverageDuration: int(row.AverageDuration),
}
}

// Convert to JSON
jsonData, err := json.MarshalIndent(results, "", " ")
if err != nil {
return fmt.Errorf("failed to marshal JSON: %w", err)
}

// Ensure the directory exists
dir := fmt.Sprintf("%s", o.OutputFile[:strings.LastIndex(o.OutputFile, "/")])
if err := os.MkdirAll(dir, 0755); err != nil {
return fmt.Errorf("failed to create output directory: %w", err)
}

// Write output to file
err = os.WriteFile(o.OutputFile, jsonData, 0644)
if err != nil {
return fmt.Errorf("failed to write output file: %w", err)
}
fmt.Fprintf(o.Out, "Test duration data written to %s\n", o.OutputFile)

return nil
}

// buildQuery constructs the BigQuery SQL query
func (o *DurationsOptions) buildQuery() string {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you tested it with openshift-ci-data-analysis.ci_data.JobTestSummaryByDate noted in TRT-2389? Thought being that using the daily summary would be more cost effective over time. Also considered this being part of jobrunhistoricaldataanalyzer

Copy link
Member Author

@stbenjam stbenjam Nov 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JobTestSummaryByDate appears to be job-level data? I only care about average test duration

Copy link
Member Author

@stbenjam stbenjam Nov 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, maybe TestsSummaryByDate? It is still grouped by job. I'm not sure I care about job-level data, I just need a rough estimate for test duration, and my JUnit query is only 13GB here and I'd guess we only care to run it at most once a day or week.

I'm a little concerned about building things in our repos on bespoke tables without schema management, especially if we'll plan to eventually try to change our data sources. Relying on JUnit makes various things easier to move en masse if we need to because its widely used

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, openshift-ci-data-analysis.ci_data.TestsSummaryByDate my bad.

We have a whole process setup that does this already for disruption and alert data. We have a job that runs weekly to update the data. It would make sense to me to have this logic running in the same process and if ci-tool already works with biq query then keeping the logic over there makes more sense to me as well.

return fmt.Sprintf(`
SELECT
test_name,
ROUND(AVG(duration_ms / 1000.0)) as average_duration
FROM `+"`%s.%s.%s`"+`
WHERE
modified_time >= DATETIME_SUB(CURRENT_DATETIME(), INTERVAL %d DAY)
AND testsuite LIKE '%%openshift-tests%%'
GROUP BY test_name
ORDER BY test_name
`, o.ProjectID, o.DatasetID, o.TableID, o.Days)
}
14 changes: 14 additions & 0 deletions pkg/cmd/openshift-tests/generate/durations/durations_flags.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package durations

import (
"github.com/spf13/pflag"
)

// AddFlags adds command-line flags to the provided flagset
func (o *DurationsOptions) AddFlags(flags *pflag.FlagSet) {
flags.StringVar(&o.ProjectID, "project", o.ProjectID, "BigQuery project ID")
flags.StringVar(&o.DatasetID, "dataset", o.DatasetID, "BigQuery dataset ID")
flags.StringVar(&o.TableID, "table", o.TableID, "BigQuery table ID")
flags.IntVar(&o.Days, "days", o.Days, "Number of days to look back for test data")
flags.StringVar(&o.OutputFile, "output", o.OutputFile, "Output file path")
}
65 changes: 65 additions & 0 deletions pkg/cmd/openshift-tests/generate/durations/durations_options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package durations

import (
"fmt"

"k8s.io/cli-runtime/pkg/genericclioptions"
)

// DurationsOptions contains the options for the durations command
type DurationsOptions struct {
// BigQuery configuration
ProjectID string
DatasetID string
TableID string

// Query configuration
Days int

// Output configuration
OutputFile string

// IO streams
genericclioptions.IOStreams
}

// NewDurationsOptions creates a new DurationsOptions with default values
func NewDurationsOptions(streams genericclioptions.IOStreams) *DurationsOptions {
return &DurationsOptions{
ProjectID: "openshift-gce-devel",
DatasetID: "ci_analysis_us",
TableID: "junit",
Days: 7,
OutputFile: "pkg/test/ginkgo/testDurations.json",
IOStreams: streams,
}
}

// Complete completes the options based on command arguments
func (o *DurationsOptions) Complete(args []string) error {
// No arguments expected for this command
if len(args) > 0 {
return fmt.Errorf("no arguments are expected")
}
return nil
}

// Validate validates the options
func (o *DurationsOptions) Validate() error {
if o.ProjectID == "" {
return fmt.Errorf("project ID cannot be empty")
}
if o.DatasetID == "" {
return fmt.Errorf("dataset ID cannot be empty")
}
if o.TableID == "" {
return fmt.Errorf("table ID cannot be empty")
}
if o.Days <= 0 {
return fmt.Errorf("days must be a positive integer")
}
if o.Days > 365 {
return fmt.Errorf("days cannot exceed 365")
}
return nil
}
Loading