github.com/tiagovtristao/plz@v13.4.0+incompatible/src/follow/marshalling.go (about) 1 // +build !bootstrap 2 3 // Contains routines to marshal between internal structures and 4 // proto-generated equivalents. 5 // The duplication is unfortunate but it's preferable to needing 6 // to run proto / gRPC compilers at bootstrap time. 7 8 package follow 9 10 import ( 11 "errors" 12 "time" 13 14 "github.com/thought-machine/please/src/core" 15 pb "github.com/thought-machine/please/src/follow/proto/build_event" 16 ) 17 18 // toProto converts an internal test result into a proto type. 19 func toProto(r *core.BuildResult) *pb.BuildEventResponse { 20 t := &r.Tests 21 return &pb.BuildEventResponse{ 22 ThreadId: int32(r.ThreadID), 23 Timestamp: r.Time.UnixNano(), 24 BuildLabel: toProtoBuildLabel(r.Label), 25 Status: pb.BuildResultStatus(r.Status), 26 Error: toProtoError(r.Err), 27 Description: r.Description, 28 TestResults: &pb.TestSuite{ 29 Package: t.Package, 30 Name: t.Name, 31 TestCases: toProtoTestCases(t.TestCases), 32 Duration: int64(t.Duration), 33 Cached: t.Cached, 34 TimedOut: t.TimedOut, 35 Properties: t.Properties, 36 Timestamp: t.Timestamp, 37 }, 38 } 39 } 40 41 // toProtos converts a slice of internal test results to a slice of protos. 42 func toProtos(results []*core.BuildResult, active, done int) []*pb.BuildEventResponse { 43 ret := make([]*pb.BuildEventResponse, 0, len(results)) 44 for _, r := range results { 45 if r != nil { 46 p := toProto(r) 47 p.NumActive = int64(active) 48 p.NumDone = int64(done) 49 ret = append(ret, p) 50 } 51 } 52 return ret 53 } 54 55 // toProtoTestCases converts a slice of test failures to the proto equivalent. 56 func toProtoTestCases(results []core.TestCase) []*pb.TestCase { 57 ret := make([]*pb.TestCase, len(results)) 58 for i, r := range results { 59 ret[i] = &pb.TestCase{ 60 ClassName: r.ClassName, 61 Name: r.Name, 62 TestExecutions: toProtoTestExecutions(r.Executions), 63 } 64 } 65 return ret 66 } 67 68 func toProtoTestExecutions(executions []core.TestExecution) []*pb.TestExecution { 69 ret := make([]*pb.TestExecution, len(executions)) 70 for i, r := range executions { 71 ret[i] = &pb.TestExecution{ 72 Failure: toTestFailure(r.Failure), 73 Error: toTestFailure(r.Error), 74 Skip: toTestSkip(r.Skip), 75 Stdout: r.Stdout, 76 Stderr: r.Stderr, 77 } 78 } 79 return ret 80 } 81 82 func toTestFailure(f *core.TestResultFailure) *pb.TestFailure { 83 if f == nil { 84 return nil 85 } 86 return &pb.TestFailure{ 87 Type: f.Type, 88 Message: f.Message, 89 Traceback: f.Traceback, 90 } 91 } 92 93 func toTestSkip(s *core.TestResultSkip) *pb.TestSkip { 94 if s == nil { 95 return nil 96 } 97 return &pb.TestSkip{ 98 Message: s.Message, 99 } 100 } 101 102 // toProtoBuildLabel converts the internal build label type to a proto equivalent. 103 func toProtoBuildLabel(label core.BuildLabel) *pb.BuildLabel { 104 return &pb.BuildLabel{PackageName: label.PackageName, Name: label.Name} 105 } 106 107 // toProtoError converts an error to a string if the error is non-nil. 108 func toProtoError(err error) string { 109 if err != nil { 110 return err.Error() 111 } 112 return "" 113 } 114 115 // fromProto converts from a proto type into the internal equivalent. 116 func fromProto(r *pb.BuildEventResponse) *core.BuildResult { 117 t := r.TestResults 118 return &core.BuildResult{ 119 ThreadID: int(r.ThreadId), 120 Time: time.Unix(0, r.Timestamp), 121 Label: fromProtoBuildLabel(r.BuildLabel), 122 Status: core.BuildResultStatus(r.Status), 123 Err: fromProtoError(r.Error), 124 Description: r.Description, 125 Tests: core.TestSuite{ 126 Package: t.Package, 127 Duration: time.Duration(t.Duration), 128 Properties: t.Properties, 129 Timestamp: t.Timestamp, 130 Name: t.Name, 131 TestCases: fromProtoTestCases(t.TestCases), 132 Cached: t.Cached, 133 TimedOut: t.TimedOut, 134 }, 135 } 136 } 137 138 // fromProtoTestResults converts a slice of proto test failures to the internal equivalent. 139 func fromProtoTestCases(results []*pb.TestCase) []core.TestCase { 140 ret := make([]core.TestCase, len(results)) 141 for i, r := range results { 142 ret[i] = core.TestCase{ 143 ClassName: r.ClassName, 144 Name: r.Name, 145 Executions: fromProtoTestExecutions(r.TestExecutions), 146 } 147 } 148 return ret 149 } 150 151 func fromProtoTestExecutions(executions []*pb.TestExecution) []core.TestExecution { 152 ret := make([]core.TestExecution, len(executions)) 153 for i, r := range executions { 154 duration := time.Duration(r.Duration) 155 ret[i] = core.TestExecution{ 156 Failure: fromProtoTestFailure(r.Failure), 157 Error: fromProtoTestFailure(r.Error), 158 Skip: fromProtoTestSkip(r.Skip), 159 Stdout: r.Stdout, 160 Stderr: r.Stderr, 161 Duration: &duration, 162 } 163 } 164 return ret 165 } 166 167 func fromProtoTestFailure(f *pb.TestFailure) *core.TestResultFailure { 168 if f == nil { 169 return nil 170 } 171 return &core.TestResultFailure{ 172 Type: f.Type, 173 Message: f.Message, 174 Traceback: f.Traceback, 175 } 176 } 177 178 func fromProtoTestSkip(s *pb.TestSkip) *core.TestResultSkip { 179 if s == nil { 180 return nil 181 } 182 return &core.TestResultSkip{ 183 Message: s.Message, 184 } 185 } 186 187 // fromProtoBuildLabel converts a proto build label to the internal version. 188 func fromProtoBuildLabel(label *pb.BuildLabel) core.BuildLabel { 189 return core.BuildLabel{PackageName: label.PackageName, Name: label.Name} 190 } 191 192 // fromProtoBuildLabels converts a series of proto build labels to a slice of internal ones. 193 func fromProtoBuildLabels(labels []*pb.BuildLabel) []core.BuildLabel { 194 ret := make([]core.BuildLabel, len(labels)) 195 for i, l := range labels { 196 ret[i] = fromProtoBuildLabel(l) 197 } 198 return ret 199 } 200 201 // fromProtoError converts a proto string into an error if it's non-empty. 202 func fromProtoError(s string) error { 203 if s != "" { 204 return errors.New(s) 205 } 206 return nil 207 } 208 209 // resourceToProto converts the internal resource stats to a proto message. 210 func resourceToProto(stats *core.SystemStats) *pb.ResourceUsageResponse { 211 return &pb.ResourceUsageResponse{ 212 NumCpus: int32(stats.CPU.Count), 213 CpuUse: stats.CPU.Used, 214 IoWait: stats.CPU.IOWait, 215 MemTotal: stats.Memory.Total, 216 MemUsed: stats.Memory.Used, 217 NumWorkerProcesses: int32(stats.NumWorkerProcesses), 218 } 219 } 220 221 // resourceFromProto converts the proto message back to the internal type. 222 func resourceFromProto(r *pb.ResourceUsageResponse) *core.SystemStats { 223 s := &core.SystemStats{} 224 s.CPU.Count = int(r.NumCpus) 225 s.CPU.Used = r.CpuUse 226 s.CPU.IOWait = r.IoWait 227 s.Memory.Total = r.MemTotal 228 s.Memory.Used = r.MemUsed 229 s.Memory.UsedPercent = 100.0 * float64(r.MemUsed) / float64(r.MemTotal) 230 s.NumWorkerProcesses = int(r.NumWorkerProcesses) 231 return s 232 }