From d0be2109cf0abd0a3668bcbac45df8e5e3e87ccd Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Tue, 26 Nov 2019 16:16:57 -0800 Subject: [PATCH] Add CUJ tests Add a cuj_tests binary that runs through a sequence of critical user journey builds and collects metrics. Bug: 145688720 Test: cuj_tests Change-Id: I6bb1a3fc4a458fd8cea7b7c924f565d0cf3e6df3 --- cuj/Android.bp | 12 ++ cuj/cuj.go | 190 ++++++++++++++++++++++++ cuj/run_cuj_tests.sh | 29 ++++ ui/metrics/metrics.go | 33 ++++- ui/metrics/metrics_proto/metrics.pb.go | 193 ++++++++++++++++++------- ui/metrics/metrics_proto/metrics.proto | 13 ++ 6 files changed, 414 insertions(+), 56 deletions(-) create mode 100644 cuj/Android.bp create mode 100644 cuj/cuj.go create mode 100755 cuj/run_cuj_tests.sh diff --git a/cuj/Android.bp b/cuj/Android.bp new file mode 100644 index 000000000..21d667f3c --- /dev/null +++ b/cuj/Android.bp @@ -0,0 +1,12 @@ +blueprint_go_binary { + name: "cuj_tests", + deps: [ + "soong-ui-build", + "soong-ui-logger", + "soong-ui-terminal", + "soong-ui-tracer", + ], + srcs: [ + "cuj.go", + ], +} diff --git a/cuj/cuj.go b/cuj/cuj.go new file mode 100644 index 000000000..c7ff8ffa8 --- /dev/null +++ b/cuj/cuj.go @@ -0,0 +1,190 @@ +// Copyright 2019 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This executable runs a series of build commands to test and benchmark some critical user journeys. +package main + +import ( + "context" + "fmt" + "os" + "path/filepath" + "strconv" + "strings" + "time" + + "android/soong/ui/build" + "android/soong/ui/logger" + "android/soong/ui/metrics" + "android/soong/ui/status" + "android/soong/ui/terminal" + "android/soong/ui/tracer" +) + +type Test struct { + name string + args []string + + results TestResults +} + +type TestResults struct { + metrics *metrics.Metrics + err error +} + +// Run runs a single build command. It emulates the "m" command line by calling into Soong UI directly. +func (t *Test) Run(logsDir string) { + output := terminal.NewStatusOutput(os.Stdout, "", false, false) + + log := logger.New(output) + defer log.Cleanup() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + trace := tracer.New(log) + defer trace.Close() + + met := metrics.New() + + stat := &status.Status{} + defer stat.Finish() + stat.AddOutput(output) + stat.AddOutput(trace.StatusTracer()) + + build.SetupSignals(log, cancel, func() { + trace.Close() + log.Cleanup() + stat.Finish() + }) + + buildCtx := build.Context{ContextImpl: &build.ContextImpl{ + Context: ctx, + Logger: log, + Metrics: met, + Tracer: trace, + Writer: output, + Status: stat, + }} + + defer logger.Recover(func(err error) { + t.results.err = err + }) + + config := build.NewConfig(buildCtx, t.args...) + build.SetupOutDir(buildCtx, config) + + os.MkdirAll(logsDir, 0777) + log.SetOutput(filepath.Join(logsDir, "soong.log")) + trace.SetOutput(filepath.Join(logsDir, "build.trace")) + stat.AddOutput(status.NewVerboseLog(log, filepath.Join(logsDir, "verbose.log"))) + stat.AddOutput(status.NewErrorLog(log, filepath.Join(logsDir, "error.log"))) + stat.AddOutput(status.NewProtoErrorLog(log, filepath.Join(logsDir, "build_error"))) + stat.AddOutput(status.NewCriticalPath(log)) + + defer met.Dump(filepath.Join(logsDir, "soong_metrics")) + + if start, ok := os.LookupEnv("TRACE_BEGIN_SOONG"); ok { + if !strings.HasSuffix(start, "N") { + if start_time, err := strconv.ParseUint(start, 10, 64); err == nil { + log.Verbosef("Took %dms to start up.", + time.Since(time.Unix(0, int64(start_time))).Nanoseconds()/time.Millisecond.Nanoseconds()) + buildCtx.CompleteTrace(metrics.RunSetupTool, "startup", start_time, uint64(time.Now().UnixNano())) + } + } + + if executable, err := os.Executable(); err == nil { + trace.ImportMicrofactoryLog(filepath.Join(filepath.Dir(executable), "."+filepath.Base(executable)+".trace")) + } + } + + f := build.NewSourceFinder(buildCtx, config) + defer f.Shutdown() + build.FindSources(buildCtx, config, f) + + build.Build(buildCtx, config, build.BuildAll) + + t.results.metrics = met +} + +func main() { + outDir := os.Getenv("OUT_DIR") + if outDir == "" { + outDir = "out" + } + + cujDir := filepath.Join(outDir, "cuj_tests") + + // Use a subdirectory for the out directory for the tests to keep them isolated. + os.Setenv("OUT_DIR", filepath.Join(cujDir, "out")) + + // Each of these tests is run in sequence without resetting the output tree. The state of the output tree will + // affect each successive test. To maintain the validity of the benchmarks across changes, care must be taken + // to avoid changing the state of the tree when a test is run. This is most easily accomplished by adding tests + // at the end. + tests := []Test{ + { + // Reset the out directory to get reproducible results. + name: "clean", + args: []string{"clean"}, + }, + { + // Parse the build files. + name: "nothing", + args: []string{"nothing"}, + }, + { + // Parse the build files again to monitor issues like globs rerunning. + name: "nothing_rebuild", + args: []string{"nothing"}, + }, + { + // Parse the build files again, this should always be very short. + name: "nothing_rebuild_twice", + args: []string{"nothing"}, + }, + { + // Build the framework as a common developer task and one that keeps getting longer. + name: "framework", + args: []string{"framework"}, + }, + { + // Build the framework again to make sure it doesn't rebuild anything. + name: "framework_rebuild", + args: []string{"framework"}, + }, + { + // Build the framework again to make sure it doesn't rebuild anything even if it did the second time. + name: "framework_rebuild_twice", + args: []string{"framework"}, + }, + } + + cujMetrics := metrics.NewCriticalUserJourneysMetrics() + defer cujMetrics.Dump(filepath.Join(cujDir, "logs", "cuj_metrics.pb")) + + for i, t := range tests { + logsSubDir := fmt.Sprintf("%02d_%s", i, t.name) + logsDir := filepath.Join(cujDir, "logs", logsSubDir) + t.Run(logsDir) + if t.results.err != nil { + fmt.Printf("error running test %q: %s\n", t.name, t.results.err) + break + } + if t.results.metrics != nil { + cujMetrics.Add(t.name, t.results.metrics) + } + } +} diff --git a/cuj/run_cuj_tests.sh b/cuj/run_cuj_tests.sh new file mode 100755 index 000000000..b4f9f8895 --- /dev/null +++ b/cuj/run_cuj_tests.sh @@ -0,0 +1,29 @@ +#!/bin/bash -e + +readonly UNAME="$(uname)" +case "$UNAME" in +Linux) + readonly OS='linux' + ;; +Darwin) + readonly OS='darwin' + ;; +*) + echo "Unsupported OS '$UNAME'" + exit 1 + ;; +esac + +readonly ANDROID_TOP="$(cd $(dirname $0)/../../..; pwd)" +cd "$ANDROID_TOP" + +export OUT_DIR="${OUT_DIR:-out}" +readonly SOONG_OUT="${OUT_DIR}/soong" + +build/soong/soong_ui.bash --make-mode "${SOONG_OUT}/host/${OS}-x86/bin/cuj_tests" + +"${SOONG_OUT}/host/${OS}-x86/bin/cuj_tests" || true + +if [ -n "${DIST_DIR}" ]; then + cp -r "${OUT_DIR}/cuj_tests/logs" "${DIST_DIR}" +fi diff --git a/ui/metrics/metrics.go b/ui/metrics/metrics.go index bc86f0a8f..64bbbf3a2 100644 --- a/ui/metrics/metrics.go +++ b/ui/metrics/metrics.go @@ -19,9 +19,9 @@ import ( "os" "strconv" - "android/soong/ui/metrics/metrics_proto" - "github.com/golang/protobuf/proto" + + soong_metrics_proto "android/soong/ui/metrics/metrics_proto" ) const ( @@ -137,13 +137,32 @@ func (m *Metrics) SetBuildDateTime(date_time string) { } } -func (m *Metrics) Serialize() (data []byte, err error) { - return proto.Marshal(&m.metrics) -} - // exports the output to the file at outputPath func (m *Metrics) Dump(outputPath string) (err error) { - data, err := m.Serialize() + return writeMessageToFile(&m.metrics, outputPath) +} + +type CriticalUserJourneysMetrics struct { + cujs soong_metrics_proto.CriticalUserJourneysMetrics +} + +func NewCriticalUserJourneysMetrics() *CriticalUserJourneysMetrics { + return &CriticalUserJourneysMetrics{} +} + +func (c *CriticalUserJourneysMetrics) Add(name string, metrics *Metrics) { + c.cujs.Cujs = append(c.cujs.Cujs, &soong_metrics_proto.CriticalUserJourneyMetrics{ + Name: proto.String(name), + Metrics: &metrics.metrics, + }) +} + +func (c *CriticalUserJourneysMetrics) Dump(outputPath string) (err error) { + return writeMessageToFile(&c.cujs, outputPath) +} + +func writeMessageToFile(pb proto.Message, outputPath string) (err error) { + data, err := proto.Marshal(pb) if err != nil { return err } diff --git a/ui/metrics/metrics_proto/metrics.pb.go b/ui/metrics/metrics_proto/metrics.pb.go index 5486ec1e6..0fe5a0db9 100644 --- a/ui/metrics/metrics_proto/metrics.pb.go +++ b/ui/metrics/metrics_proto/metrics.pb.go @@ -509,6 +509,95 @@ func (m *ModuleTypeInfo) GetNumOfModules() uint32 { return 0 } +type CriticalUserJourneyMetrics struct { + // The name of a critical user journey test. + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + // The metrics produced when running the critical user journey test. + Metrics *MetricsBase `protobuf:"bytes,2,opt,name=metrics" json:"metrics,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CriticalUserJourneyMetrics) Reset() { *m = CriticalUserJourneyMetrics{} } +func (m *CriticalUserJourneyMetrics) String() string { return proto.CompactTextString(m) } +func (*CriticalUserJourneyMetrics) ProtoMessage() {} +func (*CriticalUserJourneyMetrics) Descriptor() ([]byte, []int) { + return fileDescriptor_6039342a2ba47b72, []int{3} +} + +func (m *CriticalUserJourneyMetrics) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CriticalUserJourneyMetrics.Unmarshal(m, b) +} +func (m *CriticalUserJourneyMetrics) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CriticalUserJourneyMetrics.Marshal(b, m, deterministic) +} +func (m *CriticalUserJourneyMetrics) XXX_Merge(src proto.Message) { + xxx_messageInfo_CriticalUserJourneyMetrics.Merge(m, src) +} +func (m *CriticalUserJourneyMetrics) XXX_Size() int { + return xxx_messageInfo_CriticalUserJourneyMetrics.Size(m) +} +func (m *CriticalUserJourneyMetrics) XXX_DiscardUnknown() { + xxx_messageInfo_CriticalUserJourneyMetrics.DiscardUnknown(m) +} + +var xxx_messageInfo_CriticalUserJourneyMetrics proto.InternalMessageInfo + +func (m *CriticalUserJourneyMetrics) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *CriticalUserJourneyMetrics) GetMetrics() *MetricsBase { + if m != nil { + return m.Metrics + } + return nil +} + +type CriticalUserJourneysMetrics struct { + // A set of metrics from a run of the critical user journey tests. + Cujs []*CriticalUserJourneyMetrics `protobuf:"bytes,1,rep,name=cujs" json:"cujs,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CriticalUserJourneysMetrics) Reset() { *m = CriticalUserJourneysMetrics{} } +func (m *CriticalUserJourneysMetrics) String() string { return proto.CompactTextString(m) } +func (*CriticalUserJourneysMetrics) ProtoMessage() {} +func (*CriticalUserJourneysMetrics) Descriptor() ([]byte, []int) { + return fileDescriptor_6039342a2ba47b72, []int{4} +} + +func (m *CriticalUserJourneysMetrics) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CriticalUserJourneysMetrics.Unmarshal(m, b) +} +func (m *CriticalUserJourneysMetrics) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CriticalUserJourneysMetrics.Marshal(b, m, deterministic) +} +func (m *CriticalUserJourneysMetrics) XXX_Merge(src proto.Message) { + xxx_messageInfo_CriticalUserJourneysMetrics.Merge(m, src) +} +func (m *CriticalUserJourneysMetrics) XXX_Size() int { + return xxx_messageInfo_CriticalUserJourneysMetrics.Size(m) +} +func (m *CriticalUserJourneysMetrics) XXX_DiscardUnknown() { + xxx_messageInfo_CriticalUserJourneysMetrics.DiscardUnknown(m) +} + +var xxx_messageInfo_CriticalUserJourneysMetrics proto.InternalMessageInfo + +func (m *CriticalUserJourneysMetrics) GetCujs() []*CriticalUserJourneyMetrics { + if m != nil { + return m.Cujs + } + return nil +} + func init() { proto.RegisterEnum("soong_build_metrics.MetricsBase_BuildVariant", MetricsBase_BuildVariant_name, MetricsBase_BuildVariant_value) proto.RegisterEnum("soong_build_metrics.MetricsBase_Arch", MetricsBase_Arch_name, MetricsBase_Arch_value) @@ -516,59 +605,65 @@ func init() { proto.RegisterType((*MetricsBase)(nil), "soong_build_metrics.MetricsBase") proto.RegisterType((*PerfInfo)(nil), "soong_build_metrics.PerfInfo") proto.RegisterType((*ModuleTypeInfo)(nil), "soong_build_metrics.ModuleTypeInfo") + proto.RegisterType((*CriticalUserJourneyMetrics)(nil), "soong_build_metrics.CriticalUserJourneyMetrics") + proto.RegisterType((*CriticalUserJourneysMetrics)(nil), "soong_build_metrics.CriticalUserJourneysMetrics") } func init() { proto.RegisterFile("metrics.proto", fileDescriptor_6039342a2ba47b72) } var fileDescriptor_6039342a2ba47b72 = []byte{ - // 769 bytes of a gzipped FileDescriptorProto + // 834 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x55, 0x6f, 0x6b, 0xdb, 0x46, - 0x18, 0xaf, 0x62, 0x25, 0x96, 0x1e, 0xc5, 0xae, 0x7a, 0xc9, 0xa8, 0xca, 0x08, 0x33, 0x66, 0x1d, - 0x7e, 0xb1, 0xba, 0xc5, 0x14, 0x53, 0x4c, 0x19, 0xd8, 0x89, 0x29, 0x25, 0xd8, 0x2e, 0x4a, 0xdc, - 0x95, 0xed, 0xc5, 0xa1, 0x4a, 0xe7, 0x46, 0x9b, 0xa5, 0x13, 0x77, 0xa7, 0x32, 0x7f, 0x88, 0x7d, - 0x93, 0x7d, 0xad, 0x7d, 0x8f, 0x71, 0xcf, 0x49, 0x8e, 0x02, 0x81, 0x85, 0xbe, 0x3b, 0x3d, 0xbf, - 0x3f, 0xf7, 0x7b, 0x4e, 0xba, 0x47, 0xd0, 0xc9, 0x98, 0x12, 0x69, 0x2c, 0x87, 0x85, 0xe0, 0x8a, - 0x93, 0x13, 0xc9, 0x79, 0xfe, 0x85, 0x7e, 0x2e, 0xd3, 0x6d, 0x42, 0x2b, 0xa8, 0xff, 0x8f, 0x0b, - 0xde, 0xc2, 0xac, 0x67, 0x91, 0x64, 0xe4, 0x15, 0x9c, 0x1a, 0x42, 0x12, 0x29, 0x46, 0x55, 0x9a, - 0x31, 0xa9, 0xa2, 0xac, 0x08, 0xac, 0x9e, 0x35, 0x68, 0x85, 0x04, 0xb1, 0x8b, 0x48, 0xb1, 0xeb, - 0x1a, 0x21, 0xcf, 0xc0, 0x31, 0x8a, 0x34, 0x09, 0x0e, 0x7a, 0xd6, 0xc0, 0x0d, 0xdb, 0xf8, 0xfc, - 0x3e, 0x21, 0x13, 0x78, 0x56, 0x6c, 0x23, 0xb5, 0xe1, 0x22, 0xa3, 0x5f, 0x99, 0x90, 0x29, 0xcf, - 0x69, 0xcc, 0x13, 0x96, 0x47, 0x19, 0x0b, 0x5a, 0xc8, 0x7d, 0x5a, 0x13, 0x3e, 0x1a, 0xfc, 0xbc, - 0x82, 0xc9, 0x73, 0xe8, 0xaa, 0x48, 0x7c, 0x61, 0x8a, 0x16, 0x82, 0x27, 0x65, 0xac, 0x02, 0x1b, - 0x05, 0x1d, 0x53, 0xfd, 0x60, 0x8a, 0x24, 0x81, 0xd3, 0x8a, 0x66, 0x42, 0x7c, 0x8d, 0x44, 0x1a, - 0xe5, 0x2a, 0x38, 0xec, 0x59, 0x83, 0xee, 0xe8, 0xc5, 0xf0, 0x9e, 0x9e, 0x87, 0x8d, 0x7e, 0x87, - 0x33, 0x8d, 0x7c, 0x34, 0xa2, 0x49, 0x6b, 0xbe, 0x7c, 0x17, 0x12, 0xe3, 0xd7, 0x04, 0xc8, 0x0a, - 0xbc, 0x6a, 0x97, 0x48, 0xc4, 0x37, 0xc1, 0x11, 0x9a, 0x3f, 0xff, 0x5f, 0xf3, 0xa9, 0x88, 0x6f, - 0x26, 0xed, 0xf5, 0xf2, 0x72, 0xb9, 0xfa, 0x75, 0x19, 0x82, 0xb1, 0xd0, 0x45, 0x32, 0x84, 0x93, - 0x86, 0xe1, 0x3e, 0x75, 0x1b, 0x5b, 0x7c, 0x72, 0x4b, 0xac, 0x03, 0xfc, 0x0c, 0x55, 0x2c, 0x1a, - 0x17, 0xe5, 0x9e, 0xee, 0x20, 0xdd, 0x37, 0xc8, 0x79, 0x51, 0xd6, 0xec, 0x4b, 0x70, 0x6f, 0xb8, - 0xac, 0xc2, 0xba, 0xdf, 0x14, 0xd6, 0xd1, 0x06, 0x18, 0x35, 0x84, 0x0e, 0x9a, 0x8d, 0xf2, 0xc4, - 0x18, 0xc2, 0x37, 0x19, 0x7a, 0xda, 0x64, 0x94, 0x27, 0xe8, 0xf9, 0x14, 0xda, 0xe8, 0xc9, 0x65, - 0xe0, 0x61, 0x0f, 0x47, 0xfa, 0x71, 0x25, 0x49, 0xbf, 0xda, 0x8c, 0x4b, 0xca, 0xfe, 0x52, 0x22, - 0x0a, 0x8e, 0x11, 0xf6, 0x0c, 0x3c, 0xd7, 0xa5, 0x3d, 0x27, 0x16, 0x5c, 0x4a, 0x6d, 0xd1, 0xb9, - 0xe5, 0x9c, 0xeb, 0xda, 0x4a, 0x92, 0x9f, 0xe0, 0x71, 0x83, 0x83, 0xb1, 0xbb, 0xe6, 0xf3, 0xd9, - 0xb3, 0x30, 0xc8, 0x0b, 0x38, 0x69, 0xf0, 0xf6, 0x2d, 0x3e, 0x36, 0x07, 0xbb, 0xe7, 0x36, 0x72, - 0xf3, 0x52, 0xd1, 0x24, 0x15, 0x81, 0x6f, 0x72, 0xf3, 0x52, 0x5d, 0xa4, 0x82, 0xfc, 0x02, 0x9e, - 0x64, 0xaa, 0x2c, 0xa8, 0xe2, 0x7c, 0x2b, 0x83, 0x27, 0xbd, 0xd6, 0xc0, 0x1b, 0x9d, 0xdd, 0x7b, - 0x44, 0x1f, 0x98, 0xd8, 0xbc, 0xcf, 0x37, 0x3c, 0x04, 0x54, 0x5c, 0x6b, 0x01, 0x99, 0x80, 0xfb, - 0x67, 0xa4, 0x52, 0x2a, 0xca, 0x5c, 0x06, 0xe4, 0x21, 0x6a, 0x47, 0xf3, 0xc3, 0x32, 0x97, 0xe4, - 0x2d, 0x80, 0x61, 0xa2, 0xf8, 0xe4, 0x21, 0x62, 0x17, 0xd1, 0x5a, 0x9d, 0xa7, 0xf9, 0x1f, 0x91, - 0x51, 0x9f, 0x3e, 0x48, 0x8d, 0x02, 0xad, 0xee, 0xbf, 0x82, 0xe3, 0x3b, 0x17, 0xc5, 0x01, 0x7b, - 0x7d, 0x35, 0x0f, 0xfd, 0x47, 0xa4, 0x03, 0xae, 0x5e, 0x5d, 0xcc, 0x67, 0xeb, 0x77, 0xbe, 0x45, - 0xda, 0xa0, 0x2f, 0x97, 0x7f, 0xd0, 0x7f, 0x0b, 0x36, 0x1e, 0xa5, 0x07, 0xf5, 0xa7, 0xe1, 0x3f, - 0xd2, 0xe8, 0x34, 0x5c, 0xf8, 0x16, 0x71, 0xe1, 0x70, 0x1a, 0x2e, 0xc6, 0xaf, 0xfd, 0x03, 0x5d, - 0xfb, 0xf4, 0x66, 0xec, 0xb7, 0x08, 0xc0, 0xd1, 0xa7, 0x37, 0x63, 0x3a, 0x7e, 0xed, 0xdb, 0xfd, - 0xbf, 0x2d, 0x70, 0xea, 0x1c, 0x84, 0x80, 0x9d, 0x30, 0x19, 0xe3, 0x6c, 0x72, 0x43, 0x5c, 0xeb, - 0x1a, 0x4e, 0x17, 0x33, 0x89, 0x70, 0x4d, 0xce, 0x00, 0xa4, 0x8a, 0x84, 0xc2, 0x71, 0x86, 0x73, - 0xc7, 0x0e, 0x5d, 0xac, 0xe8, 0x29, 0x46, 0xbe, 0x07, 0x57, 0xb0, 0x68, 0x6b, 0x50, 0x1b, 0x51, - 0x47, 0x17, 0x10, 0x3c, 0x03, 0xc8, 0x58, 0xc6, 0xc5, 0x8e, 0x96, 0x92, 0xe1, 0x54, 0xb1, 0x43, - 0xd7, 0x54, 0xd6, 0x92, 0xf5, 0xff, 0xb5, 0xa0, 0xbb, 0xe0, 0x49, 0xb9, 0x65, 0xd7, 0xbb, 0x82, - 0x61, 0xaa, 0xdf, 0xe1, 0xd8, 0x9c, 0x9b, 0xdc, 0x49, 0xc5, 0x32, 0x4c, 0xd7, 0x1d, 0xbd, 0xbc, - 0xff, 0xba, 0xdc, 0x91, 0x9a, 0x61, 0x74, 0x85, 0xb2, 0xc6, 0xc5, 0xf9, 0x7c, 0x5b, 0x25, 0x3f, - 0x80, 0x97, 0xa1, 0x86, 0xaa, 0x5d, 0x51, 0x77, 0x09, 0xd9, 0xde, 0x86, 0xfc, 0x08, 0xdd, 0xbc, - 0xcc, 0x28, 0xdf, 0x50, 0x53, 0x94, 0xd8, 0x6f, 0x27, 0x3c, 0xce, 0xcb, 0x6c, 0xb5, 0x31, 0xfb, - 0xc9, 0xfe, 0x4b, 0xf0, 0x1a, 0x7b, 0xdd, 0x7d, 0x17, 0x2e, 0x1c, 0x5e, 0xad, 0x56, 0x4b, 0xfd, - 0xd2, 0x1c, 0xb0, 0x17, 0xd3, 0xcb, 0xb9, 0x7f, 0x30, 0xfb, 0xee, 0xb7, 0xea, 0xef, 0x51, 0x25, - 0xa7, 0xf8, 0x4b, 0xf9, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x81, 0xd0, 0x84, 0x23, 0x62, 0x06, 0x00, - 0x00, + 0x18, 0xaf, 0x62, 0x25, 0xb6, 0x1e, 0xc5, 0xae, 0x7a, 0xc9, 0xa8, 0xba, 0x12, 0x66, 0xc4, 0x3a, + 0xf2, 0x62, 0x75, 0x8b, 0x29, 0xa1, 0x98, 0x32, 0x48, 0x1c, 0x53, 0xba, 0x60, 0xbb, 0x28, 0x71, + 0x57, 0xb6, 0x17, 0x87, 0x22, 0x9d, 0x1b, 0x75, 0x96, 0x4e, 0xdc, 0x9d, 0xca, 0xfc, 0x21, 0xf6, + 0x4d, 0xf6, 0xb5, 0xf6, 0x3d, 0xc6, 0x3d, 0x27, 0x39, 0x0a, 0x78, 0x34, 0xf4, 0xdd, 0xe9, 0xf9, + 0xfd, 0xb9, 0xdf, 0x73, 0xd2, 0x3d, 0x82, 0x6e, 0xc6, 0x94, 0x48, 0x63, 0x39, 0x28, 0x04, 0x57, + 0x9c, 0x1c, 0x48, 0xce, 0xf3, 0x4f, 0xf4, 0xba, 0x4c, 0x57, 0x09, 0xad, 0xa0, 0xe0, 0x1f, 0x07, + 0xdc, 0xa9, 0x59, 0x9f, 0x45, 0x92, 0x91, 0x97, 0x70, 0x68, 0x08, 0x49, 0xa4, 0x18, 0x55, 0x69, + 0xc6, 0xa4, 0x8a, 0xb2, 0xc2, 0xb7, 0xfa, 0xd6, 0x71, 0x2b, 0x24, 0x88, 0x9d, 0x47, 0x8a, 0x5d, + 0xd5, 0x08, 0x79, 0x02, 0x1d, 0xa3, 0x48, 0x13, 0x7f, 0xa7, 0x6f, 0x1d, 0x3b, 0x61, 0x1b, 0x9f, + 0xdf, 0x25, 0x64, 0x04, 0x4f, 0x8a, 0x55, 0xa4, 0x96, 0x5c, 0x64, 0xf4, 0x0b, 0x13, 0x32, 0xe5, + 0x39, 0x8d, 0x79, 0xc2, 0xf2, 0x28, 0x63, 0x7e, 0x0b, 0xb9, 0x8f, 0x6b, 0xc2, 0x07, 0x83, 0x8f, + 0x2b, 0x98, 0x3c, 0x83, 0x9e, 0x8a, 0xc4, 0x27, 0xa6, 0x68, 0x21, 0x78, 0x52, 0xc6, 0xca, 0xb7, + 0x51, 0xd0, 0x35, 0xd5, 0xf7, 0xa6, 0x48, 0x12, 0x38, 0xac, 0x68, 0x26, 0xc4, 0x97, 0x48, 0xa4, + 0x51, 0xae, 0xfc, 0xdd, 0xbe, 0x75, 0xdc, 0x1b, 0x3e, 0x1f, 0x6c, 0xe9, 0x79, 0xd0, 0xe8, 0x77, + 0x70, 0xa6, 0x91, 0x0f, 0x46, 0x34, 0x6a, 0x4d, 0x66, 0x6f, 0x43, 0x62, 0xfc, 0x9a, 0x00, 0x99, + 0x83, 0x5b, 0xed, 0x12, 0x89, 0xf8, 0xc6, 0xdf, 0x43, 0xf3, 0x67, 0x5f, 0x35, 0x3f, 0x15, 0xf1, + 0xcd, 0xa8, 0xbd, 0x98, 0x5d, 0xcc, 0xe6, 0xbf, 0xcd, 0x42, 0x30, 0x16, 0xba, 0x48, 0x06, 0x70, + 0xd0, 0x30, 0xdc, 0xa4, 0x6e, 0x63, 0x8b, 0x8f, 0x6e, 0x89, 0x75, 0x80, 0x9f, 0xa1, 0x8a, 0x45, + 0xe3, 0xa2, 0xdc, 0xd0, 0x3b, 0x48, 0xf7, 0x0c, 0x32, 0x2e, 0xca, 0x9a, 0x7d, 0x01, 0xce, 0x0d, + 0x97, 0x55, 0x58, 0xe7, 0x9b, 0xc2, 0x76, 0xb4, 0x01, 0x46, 0x0d, 0xa1, 0x8b, 0x66, 0xc3, 0x3c, + 0x31, 0x86, 0xf0, 0x4d, 0x86, 0xae, 0x36, 0x19, 0xe6, 0x09, 0x7a, 0x3e, 0x86, 0x36, 0x7a, 0x72, + 0xe9, 0xbb, 0xd8, 0xc3, 0x9e, 0x7e, 0x9c, 0x4b, 0x12, 0x54, 0x9b, 0x71, 0x49, 0xd9, 0x5f, 0x4a, + 0x44, 0xfe, 0x3e, 0xc2, 0xae, 0x81, 0x27, 0xba, 0xb4, 0xe1, 0xc4, 0x82, 0x4b, 0xa9, 0x2d, 0xba, + 0xb7, 0x9c, 0xb1, 0xae, 0xcd, 0x25, 0xf9, 0x09, 0x1e, 0x36, 0x38, 0x18, 0xbb, 0x67, 0x3e, 0x9f, + 0x0d, 0x0b, 0x83, 0x3c, 0x87, 0x83, 0x06, 0x6f, 0xd3, 0xe2, 0x43, 0x73, 0xb0, 0x1b, 0x6e, 0x23, + 0x37, 0x2f, 0x15, 0x4d, 0x52, 0xe1, 0x7b, 0x26, 0x37, 0x2f, 0xd5, 0x79, 0x2a, 0xc8, 0x2f, 0xe0, + 0x4a, 0xa6, 0xca, 0x82, 0x2a, 0xce, 0x57, 0xd2, 0x7f, 0xd4, 0x6f, 0x1d, 0xbb, 0xc3, 0xa3, 0xad, + 0x47, 0xf4, 0x9e, 0x89, 0xe5, 0xbb, 0x7c, 0xc9, 0x43, 0x40, 0xc5, 0x95, 0x16, 0x90, 0x11, 0x38, + 0x7f, 0x46, 0x2a, 0xa5, 0xa2, 0xcc, 0xa5, 0x4f, 0xee, 0xa3, 0xee, 0x68, 0x7e, 0x58, 0xe6, 0x92, + 0xbc, 0x01, 0x30, 0x4c, 0x14, 0x1f, 0xdc, 0x47, 0xec, 0x20, 0x5a, 0xab, 0xf3, 0x34, 0xff, 0x1c, + 0x19, 0xf5, 0xe1, 0xbd, 0xd4, 0x28, 0xd0, 0xea, 0xe0, 0x25, 0xec, 0xdf, 0xb9, 0x28, 0x1d, 0xb0, + 0x17, 0x97, 0x93, 0xd0, 0x7b, 0x40, 0xba, 0xe0, 0xe8, 0xd5, 0xf9, 0xe4, 0x6c, 0xf1, 0xd6, 0xb3, + 0x48, 0x1b, 0xf4, 0xe5, 0xf2, 0x76, 0x82, 0x37, 0x60, 0xe3, 0x51, 0xba, 0x50, 0x7f, 0x1a, 0xde, + 0x03, 0x8d, 0x9e, 0x86, 0x53, 0xcf, 0x22, 0x0e, 0xec, 0x9e, 0x86, 0xd3, 0x93, 0x57, 0xde, 0x8e, + 0xae, 0x7d, 0x7c, 0x7d, 0xe2, 0xb5, 0x08, 0xc0, 0xde, 0xc7, 0xd7, 0x27, 0xf4, 0xe4, 0x95, 0x67, + 0x07, 0x7f, 0x5b, 0xd0, 0xa9, 0x73, 0x10, 0x02, 0x76, 0xc2, 0x64, 0x8c, 0xb3, 0xc9, 0x09, 0x71, + 0xad, 0x6b, 0x38, 0x5d, 0xcc, 0x24, 0xc2, 0x35, 0x39, 0x02, 0x90, 0x2a, 0x12, 0x0a, 0xc7, 0x19, + 0xce, 0x1d, 0x3b, 0x74, 0xb0, 0xa2, 0xa7, 0x18, 0x79, 0x0a, 0x8e, 0x60, 0xd1, 0xca, 0xa0, 0x36, + 0xa2, 0x1d, 0x5d, 0x40, 0xf0, 0x08, 0x20, 0x63, 0x19, 0x17, 0x6b, 0x5a, 0x4a, 0x86, 0x53, 0xc5, + 0x0e, 0x1d, 0x53, 0x59, 0x48, 0x16, 0xfc, 0x6b, 0x41, 0x6f, 0xca, 0x93, 0x72, 0xc5, 0xae, 0xd6, + 0x05, 0xc3, 0x54, 0x7f, 0xc0, 0xbe, 0x39, 0x37, 0xb9, 0x96, 0x8a, 0x65, 0x98, 0xae, 0x37, 0x7c, + 0xb1, 0xfd, 0xba, 0xdc, 0x91, 0x9a, 0x61, 0x74, 0x89, 0xb2, 0xc6, 0xc5, 0xb9, 0xbe, 0xad, 0x92, + 0x1f, 0xc0, 0xcd, 0x50, 0x43, 0xd5, 0xba, 0xa8, 0xbb, 0x84, 0x6c, 0x63, 0x43, 0x7e, 0x84, 0x5e, + 0x5e, 0x66, 0x94, 0x2f, 0xa9, 0x29, 0x4a, 0xec, 0xb7, 0x1b, 0xee, 0xe7, 0x65, 0x36, 0x5f, 0x9a, + 0xfd, 0x64, 0xf0, 0x02, 0xdc, 0xc6, 0x5e, 0x77, 0xdf, 0x85, 0x03, 0xbb, 0x97, 0xf3, 0xf9, 0x4c, + 0xbf, 0xb4, 0x0e, 0xd8, 0xd3, 0xd3, 0x8b, 0x89, 0xb7, 0x13, 0xac, 0xe0, 0xfb, 0xb1, 0x48, 0x55, + 0x1a, 0x47, 0xab, 0x85, 0x64, 0xe2, 0x57, 0x5e, 0x8a, 0x9c, 0xad, 0xab, 0xdb, 0xbe, 0x39, 0x74, + 0xab, 0x71, 0xe8, 0x23, 0x68, 0x57, 0x5d, 0x62, 0x4a, 0x77, 0xd8, 0xff, 0xda, 0xc0, 0x08, 0x6b, + 0x41, 0x70, 0x0d, 0x4f, 0xb7, 0xec, 0x26, 0xeb, 0xed, 0xc6, 0x60, 0xc7, 0xe5, 0x67, 0xe9, 0x5b, + 0xf8, 0xb1, 0x6e, 0x3f, 0xd9, 0xff, 0x4f, 0x1b, 0xa2, 0xf8, 0xec, 0xbb, 0xdf, 0xab, 0xff, 0x61, + 0xa5, 0xa0, 0xf8, 0x93, 0xfc, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x20, 0x07, 0xbc, 0xf0, 0x34, 0x07, + 0x00, 0x00, } diff --git a/ui/metrics/metrics_proto/metrics.proto b/ui/metrics/metrics_proto/metrics.proto index 93034eb8c..1ea24bfab 100644 --- a/ui/metrics/metrics_proto/metrics.proto +++ b/ui/metrics/metrics_proto/metrics.proto @@ -125,3 +125,16 @@ message ModuleTypeInfo { // The number of logical modules. optional uint32 num_of_modules = 3; } + +message CriticalUserJourneyMetrics { + // The name of a critical user journey test. + optional string name = 1; + + // The metrics produced when running the critical user journey test. + optional MetricsBase metrics = 2; +} + +message CriticalUserJourneysMetrics { + // A set of metrics from a run of the critical user journey tests. + repeated CriticalUserJourneyMetrics cujs = 1; +} \ No newline at end of file