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  }