@@ -260,9 +260,31 @@ ORDER BY j.prowjob_job_name;
260260 dur := time .Since (start )
261261 log .WithField ("count" , count .Load ()).Infof ("processed primary job list in %s" , dur )
262262
263+ var errs []string
264+ for jobName , variants := range variantsByJob {
265+ if err := validateSpotCheckVariants (jobName , variants ); err != nil {
266+ errs = append (errs , err .Error ())
267+ }
268+ }
269+ if len (errs ) > 0 {
270+ sort .Strings (errs )
271+ return nil , errors .New ("variant registry validation failed:\n " + strings .Join (errs , "\n " ))
272+ }
273+
263274 return variantsByJob , nil
264275}
265276
277+ // validateSpotCheckVariants returns an error if a job has JobTier=spotcheck without both
278+ // SpotCheckComponent and SpotCheckCapability defined.
279+ func validateSpotCheckVariants (jobName string , variants map [string ]string ) error {
280+ if strings .HasPrefix (variants [VariantJobTier ], "spotcheck-" ) {
281+ if variants [VariantSpotCheckComponent ] == "" || variants [VariantSpotCheckCapability ] == "" {
282+ return fmt .Errorf ("job %q has JobTier=%s but is missing SpotCheckComponent or SpotCheckCapability" , jobName , variants [VariantJobTier ])
283+ }
284+ }
285+ return nil
286+ }
287+
266288// fileVariantsToIgnore are values in the cluster-data.json that vary by run, and are not consistent for the job itself.
267289// These are unsuited for variants.
268290var fileVariantsToIgnore = map [string ]bool {
@@ -427,34 +449,36 @@ var (
427449)
428450
429451const (
430- VariantAggregation = "Aggregation" // aggregated or none
431- VariantArch = "Architecture"
432- VariantFeatureSet = "FeatureSet" // techpreview / standard
433- VariantInstaller = "Installer" // ipi / upi / assisted
434- VariantNetwork = "Network"
435- VariantNetworkAccess = "NetworkAccess" // disconnected / proxy / standard
436- VariantNetworkStack = "NetworkStack" // ipv4 / ipv6 / dual
437- VariantOwner = "Owner" // eng / osd
438- VariantPlatform = "Platform"
439- VariantScheduler = "Scheduler" // realtime / standard
440- VariantSecurityMode = "SecurityMode" // fips / default
441- VariantSuite = "Suite" // parallel / serial
442- VariantProcedure = "Procedure" // for jobs that do a specific procedure on the cluster (etcd scaling, cpu partitioning, etc.), and then optionally run conformance
443- VariantJobTier = "JobTier" // specifies rare, blocking, informing, standard jobs
444- VariantTopology = "Topology" // ha / single / compact / external
445- VariantUpgrade = "Upgrade"
446- VariantContainerRuntime = "ContainerRuntime" // runc / crun
447- VariantCGroupMode = "CGroupMode" // v2 / v1
448- VariantRelease = "Release"
449- VariantReleaseMinor = "ReleaseMinor"
450- VariantReleaseMajor = "ReleaseMajor"
451- VariantFromRelease = "FromRelease"
452- VariantFromReleaseMinor = "FromReleaseMinor"
453- VariantFromReleaseMajor = "FromReleaseMajor"
454- VariantLayeredProduct = "LayeredProduct"
455- VariantOS = "OS"
456- VariantDefaultValue = "default"
457- VariantNoValue = "none"
452+ VariantAggregation = "Aggregation" // aggregated or none
453+ VariantArch = "Architecture"
454+ VariantFeatureSet = "FeatureSet" // techpreview / standard
455+ VariantInstaller = "Installer" // ipi / upi / assisted
456+ VariantNetwork = "Network"
457+ VariantNetworkAccess = "NetworkAccess" // disconnected / proxy / standard
458+ VariantNetworkStack = "NetworkStack" // ipv4 / ipv6 / dual
459+ VariantOwner = "Owner" // eng / osd
460+ VariantPlatform = "Platform"
461+ VariantScheduler = "Scheduler" // realtime / standard
462+ VariantSecurityMode = "SecurityMode" // fips / default
463+ VariantSuite = "Suite" // parallel / serial
464+ VariantProcedure = "Procedure" // for jobs that do a specific procedure on the cluster (etcd scaling, cpu partitioning, etc.), and then optionally run conformance
465+ VariantJobTier = "JobTier" // specifies rare, blocking, informing, standard jobs
466+ VariantTopology = "Topology" // ha / single / compact / external
467+ VariantUpgrade = "Upgrade"
468+ VariantContainerRuntime = "ContainerRuntime" // runc / crun
469+ VariantCGroupMode = "CGroupMode" // v2 / v1
470+ VariantRelease = "Release"
471+ VariantReleaseMinor = "ReleaseMinor"
472+ VariantReleaseMajor = "ReleaseMajor"
473+ VariantFromRelease = "FromRelease"
474+ VariantFromReleaseMinor = "FromReleaseMinor"
475+ VariantFromReleaseMajor = "FromReleaseMajor"
476+ VariantLayeredProduct = "LayeredProduct"
477+ VariantOS = "OS"
478+ VariantSpotCheckComponent = "SpotCheckComponent" // component readiness component for spot-check jobs
479+ VariantSpotCheckCapability = "SpotCheckCapability" // component readiness capability for spot-check jobs
480+ VariantDefaultValue = "default"
481+ VariantNoValue = "none"
458482)
459483
460484func (v * OCPVariantLoader ) IdentifyVariants (jLog logrus.FieldLogger , jobName string ) map [string ]string {
@@ -480,6 +504,7 @@ func (v *OCPVariantLoader) IdentifyVariants(jLog logrus.FieldLogger, jobName str
480504 setContainerRuntime ,
481505 setProcedure ,
482506 setOS ,
507+ setSpotCheckClassification ,
483508 v .setJobTier , // Keep this near last, it relies on other variants like owner
484509 } {
485510 setter (jLog , variants , jobName )
@@ -726,29 +751,69 @@ func (v *OCPVariantLoader) setRelease(logger logrus.FieldLogger, variants map[st
726751 }
727752}
728753
754+ // setSpotCheckClassification identifies jobs that should be evaluated as spot-check jobs
755+ // in Component Readiness. These jobs run infrequently ("rare" tier historically) and
756+ // must fully pass at least once in the sample window. (with retries if needed)
757+ // They are intended for stable, non-core functionality that does not need in depth
758+ // statistical regression monitoring.
759+ //
760+ // The SpotCheckComponent and SpotCheckCapability variants control where these synthetic
761+ // results appear in the component readiness report.
762+ //
763+ // Be sure to use real Component names from OCPBUGS.
764+ func setSpotCheckClassification (_ logrus.FieldLogger , variants map [string ]string , jobName string ) {
765+ jobNameLower := strings .ToLower (jobName )
766+
767+ spotCheckPatterns := []struct {
768+ substrings []string
769+ component string
770+ capability string
771+ }{
772+ {[]string {"-cpu-partitioning" }, "Node / Kubelet" , "CPU Partitioning" },
773+ {[]string {"-etcd-scaling" }, "Etcd" , "Scaling" },
774+ }
775+
776+ for _ , p := range spotCheckPatterns {
777+ allMatch := true
778+ for _ , sub := range p .substrings {
779+ if ! strings .Contains (jobNameLower , sub ) {
780+ allMatch = false
781+ break
782+ }
783+ }
784+ if allMatch {
785+ variants [VariantSpotCheckComponent ] = p .component
786+ variants [VariantSpotCheckCapability ] = p .capability
787+ return
788+ }
789+ }
790+ }
791+
729792// setJobTier sets the jobTier for a job, with values like this:
730793//
731- // blocking: blocking job on payloads, covered by component readiness
732- // informing: informing job on payloads, covered by component readiness
733- // standard: should be visible in default views (component readiness, sippy), covered by component readiness
734- // rare: highly reliable jobs that run at a reduced frequency
735- // candidate: not covered by component readiness, but may be promoted in the future
736- // hidden: data should still be synced, but not shown by default
737- // excluded: data should not be synced, and excluded from all views
794+ // blocking: blocking job on payloads, covered by component readiness
795+ // informing: informing job on payloads, covered by component readiness
796+ // standard: should be visible in default views (component readiness, sippy), covered by component readiness
797+ // spotcheck: jobs evaluated by spot-check analysis (job pass/fail, not junit); views opt in via JobTier include
798+ // candidate: not covered by component readiness, but may be promoted in the future
799+ // hidden: data should still be synced, but not shown by default
800+ // excluded: data should not be synced, and excluded from all views
738801//
739802// Note: blocking/informing/standard tiers may be downgraded to candidate by
740803// adjustJobTierBasedOnView if the job's variants don't match the release-main view.
741804func (v * OCPVariantLoader ) setJobTier (_ logrus.FieldLogger , variants map [string ]string , jobName string ) {
805+ // Jobs classified as spot-check get the spotcheck-30d tier automatically.
806+ if _ , ok := variants [VariantSpotCheckComponent ]; ok {
807+ variants [VariantJobTier ] = "spotcheck-30d"
808+ return
809+ }
810+
742811 jobNameLower := strings .ToLower (jobName )
743812
744813 jobTierPatterns := []struct {
745814 substrings []string
746815 jobTier string
747816 }{
748- // Rarely run
749- {[]string {"-cpu-partitioning" }, "rare" },
750- {[]string {"-etcd-scaling" }, "rare" },
751-
752817 // QE jobs allowlisted for Component Readiness
753818 {[]string {"-automated-release" }, "standard" },
754819
0 commit comments