diff --git a/conformance/chaos/actor.go b/conformance/chaos/actor.go index ed7a230c7..f162b2c8f 100644 --- a/conformance/chaos/actor.go +++ b/conformance/chaos/actor.go @@ -62,6 +62,9 @@ const ( // MethodMutateState is the identifier for the method that attempts to mutate // a state value in the actor. MethodMutateState + // MethodAbort is the identifier for the method that panics optionally with + // a passed exit code. + MethodAbort ) // Exports defines the methods this actor exposes publicly. @@ -74,6 +77,7 @@ func (a Actor) Exports() []interface{} { MethodDeleteActor: a.DeleteActor, MethodSend: a.Send, MethodMutateState: a.MutateState, + MethodAbort: a.Abort, } } @@ -230,3 +234,21 @@ func (a Actor) MutateState(rt runtime.Runtime, args *MutateStateArgs) *adt.Empty } return nil } + +// AbortArgs are the arguments to the abort method, specifying the exit code to +// (optionally) abort with and the message. +type AbortArgs struct { + Code exitcode.ExitCode + NoCode bool + Message string +} + +// Abort simply causes a panic or abort with the passed exit code. +func (a Actor) Abort(rt runtime.Runtime, args *AbortArgs) *adt.EmptyValue { + if args.NoCode { // no code, just plain old panic + panic(args.Message) + } else { + rt.Abortf(args.Code, args.Message) + } + return nil +} diff --git a/conformance/chaos/cbor_gen.go b/conformance/chaos/cbor_gen.go index 9f01ccce7..00825c8f3 100644 --- a/conformance/chaos/cbor_gen.go +++ b/conformance/chaos/cbor_gen.go @@ -614,3 +614,119 @@ func (t *MutateStateArgs) UnmarshalCBOR(r io.Reader) error { } return nil } + +var lengthBufAbortArgs = []byte{131} + +func (t *AbortArgs) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + if _, err := w.Write(lengthBufAbortArgs); err != nil { + return err + } + + scratch := make([]byte, 9) + + // t.Code (exitcode.ExitCode) (int64) + if t.Code >= 0 { + if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajUnsignedInt, uint64(t.Code)); err != nil { + return err + } + } else { + if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajNegativeInt, uint64(-t.Code-1)); err != nil { + return err + } + } + + // t.NoCode (bool) (bool) + if err := cbg.WriteBool(w, t.NoCode); err != nil { + return err + } + + // t.Message (string) (string) + if len(t.Message) > cbg.MaxLength { + return xerrors.Errorf("Value in field t.Message was too long") + } + + if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajTextString, uint64(len(t.Message))); err != nil { + return err + } + if _, err := io.WriteString(w, string(t.Message)); err != nil { + return err + } + return nil +} + +func (t *AbortArgs) UnmarshalCBOR(r io.Reader) error { + *t = AbortArgs{} + + br := cbg.GetPeeker(r) + scratch := make([]byte, 8) + + maj, extra, err := cbg.CborReadHeaderBuf(br, scratch) + if err != nil { + return err + } + if maj != cbg.MajArray { + return fmt.Errorf("cbor input should be of type array") + } + + if extra != 3 { + return fmt.Errorf("cbor input had wrong number of fields") + } + + // t.Code (exitcode.ExitCode) (int64) + { + maj, extra, err := cbg.CborReadHeaderBuf(br, scratch) + var extraI int64 + if err != nil { + return err + } + switch maj { + case cbg.MajUnsignedInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 positive overflow") + } + case cbg.MajNegativeInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 negative oveflow") + } + extraI = -1 - extraI + default: + return fmt.Errorf("wrong type for int64 field: %d", maj) + } + + t.Code = exitcode.ExitCode(extraI) + } + // t.NoCode (bool) (bool) + + maj, extra, err = cbg.CborReadHeaderBuf(br, scratch) + if err != nil { + return err + } + if maj != cbg.MajOther { + return fmt.Errorf("booleans must be major type 7") + } + switch extra { + case 20: + t.NoCode = false + case 21: + t.NoCode = true + default: + return fmt.Errorf("booleans are either major type 7, value 20 or 21 (got %d)", extra) + } + // t.Message (string) (string) + + { + sval, err := cbg.ReadStringBuf(br, scratch) + if err != nil { + return err + } + + t.Message = string(sval) + } + return nil +} diff --git a/conformance/chaos/gen/gen.go b/conformance/chaos/gen/gen.go index 308fed11e..dbf8463d4 100644 --- a/conformance/chaos/gen/gen.go +++ b/conformance/chaos/gen/gen.go @@ -14,6 +14,7 @@ func main() { chaos.SendArgs{}, chaos.SendReturn{}, chaos.MutateStateArgs{}, + chaos.AbortArgs{}, ); err != nil { panic(err) }