diff --git a/conformance/chaos/actor.go b/conformance/chaos/actor.go index ed7a230c724..f3da42bb616 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 + // MethodAbortWith is the identifier for the method that panics optionally with + // a passed exit code. + MethodAbortWith ) // 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, + MethodAbortWith: a.AbortWith, } } @@ -230,3 +234,21 @@ func (a Actor) MutateState(rt runtime.Runtime, args *MutateStateArgs) *adt.Empty } return nil } + +// AbortWithArgs are the arguments to the Actor.AbortWith method, specifying the +// exit code to (optionally) abort with and the message. +type AbortWithArgs struct { + Code exitcode.ExitCode + Message string + Uncontrolled bool +} + +// AbortWith simply causes a panic with the passed exit code. +func (a Actor) AbortWith(rt runtime.Runtime, args *AbortWithArgs) *adt.EmptyValue { + if args.Uncontrolled { // uncontrolled abort: directly 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 9f01ccce7d6..710b84b9306 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 lengthBufAbortWithArgs = []byte{131} + +func (t *AbortWithArgs) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + if _, err := w.Write(lengthBufAbortWithArgs); 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.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 + } + + // t.Uncontrolled (bool) (bool) + if err := cbg.WriteBool(w, t.Uncontrolled); err != nil { + return err + } + return nil +} + +func (t *AbortWithArgs) UnmarshalCBOR(r io.Reader) error { + *t = AbortWithArgs{} + + 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.Message (string) (string) + + { + sval, err := cbg.ReadStringBuf(br, scratch) + if err != nil { + return err + } + + t.Message = string(sval) + } + // t.Uncontrolled (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.Uncontrolled = false + case 21: + t.Uncontrolled = true + default: + return fmt.Errorf("booleans are either major type 7, value 20 or 21 (got %d)", extra) + } + return nil +} diff --git a/conformance/chaos/gen/gen.go b/conformance/chaos/gen/gen.go index 308fed11e9b..97ea98dc8bb 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.AbortWithArgs{}, ); err != nil { panic(err) }