@@ -27,6 +27,7 @@ import (
2727 "google.golang.org/protobuf/encoding/protojson"
2828 "google.golang.org/protobuf/proto"
2929 "google.golang.org/protobuf/testing/protocmp"
30+ "google.golang.org/protobuf/types/known/durationpb"
3031 "google.golang.org/protobuf/types/known/emptypb"
3132 fieldmaskpb "google.golang.org/protobuf/types/known/fieldmaskpb"
3233 "google.golang.org/protobuf/types/known/structpb"
@@ -521,6 +522,7 @@ func TestABE(t *testing.T) {
521522 testABEDownload (t , 8088 )
522523 testABEBulkEcho (t , 8088 )
523524 testABEBulkEchoZeroLength (t , 8088 )
525+ testABEBulkEchoDurationError (t , 8088 )
524526 testAdditionalBindings (t , 8088 )
525527 testABERepeated (t , 8088 )
526528 testABEExists (t , 8088 )
@@ -1448,6 +1450,105 @@ func testABEBulkEchoZeroLength(t *testing.T, port int) {
14481450 }
14491451}
14501452
1453+ func testABEBulkEchoDurationError (t * testing.T , port int ) {
1454+ reqr , reqw := io .Pipe ()
1455+ var wg sync.WaitGroup
1456+ var want []* durationpb.Duration
1457+ wg .Add (1 )
1458+ go func () {
1459+ defer wg .Done ()
1460+ defer reqw .Close ()
1461+ for i := 0 ; i < 10 ; i ++ {
1462+ s := fmt .Sprintf ("%d.123s" , i )
1463+ buf , err := marshaler .Marshal (s )
1464+ if err != nil {
1465+ t .Errorf ("marshaler.Marshal(%v) failed with %v; want success" , s , err )
1466+ return
1467+ }
1468+ if _ , err = reqw .Write (buf ); err != nil {
1469+ t .Errorf ("reqw.Write(%q) failed with %v; want success" , string (buf ), err )
1470+ return
1471+ }
1472+ want = append (want , & durationpb.Duration {Seconds : int64 (i ), Nanos : int32 (0.123 * 1e9 )})
1473+ }
1474+ badRequest := "invalidDurationFormat"
1475+ buf , err := marshaler .Marshal (badRequest )
1476+ if err != nil {
1477+ t .Errorf ("marshaler.Marshal(%v) failed with %v; want success" , badRequest , err )
1478+ return
1479+ }
1480+ if _ , err = reqw .Write (buf ); err != nil {
1481+ t .Errorf ("reqw.Write(%q) failed with %v; want success" , string (buf ), err )
1482+ return
1483+ }
1484+ }()
1485+ apiURL := fmt .Sprintf ("http://localhost:%d/v1/example/a_bit_of_everything/echo_duration" , port )
1486+ req , err := http .NewRequest ("POST" , apiURL , reqr )
1487+ if err != nil {
1488+ t .Errorf ("http.NewRequest(%q, %q, reqr) failed with %v; want success" , "POST" , apiURL , err )
1489+ return
1490+ }
1491+ req .Header .Set ("Content-Type" , "application/json" )
1492+ req .Header .Set ("Transfer-Encoding" , "chunked" )
1493+ resp , err := http .DefaultClient .Do (req )
1494+ if err != nil {
1495+ t .Errorf ("http.Post(%q, %q, req) failed with %v; want success" , apiURL , "application/json" , err )
1496+ return
1497+ }
1498+ defer resp .Body .Close ()
1499+ if got , want := resp .StatusCode , http .StatusOK ; got != want {
1500+ t .Errorf ("resp.StatusCode = %d; want %d" , got , want )
1501+ }
1502+
1503+ var got []* durationpb.Duration
1504+ var invalidArgumentCount int
1505+ wg .Add (1 )
1506+ go func () {
1507+ defer wg .Done ()
1508+
1509+ dec := marshaler .NewDecoder (resp .Body )
1510+ for i := 0 ; ; i ++ {
1511+ var item struct {
1512+ Result json.RawMessage `json:"result"`
1513+ Error map [string ]interface {} `json:"error"`
1514+ }
1515+ err := dec .Decode (& item )
1516+ if err == io .EOF {
1517+ break
1518+ }
1519+ if err != nil {
1520+ t .Errorf ("dec.Decode(&item) failed with %v; want success; i = %d" , err , i )
1521+ }
1522+ if len (item .Error ) != 0 {
1523+ code , ok := item .Error ["code" ].(float64 )
1524+ if ! ok {
1525+ t .Errorf ("item.Error[code] not found or not a number: %#v; i = %d" , item .Error , i )
1526+ } else if int32 (code ) == 3 {
1527+ invalidArgumentCount ++
1528+ } else {
1529+ t .Errorf ("item.Error[code] = %v; want 3; i = %d" , code , i )
1530+ }
1531+ continue
1532+ }
1533+
1534+ msg := new (durationpb.Duration )
1535+ if err := marshaler .Unmarshal (item .Result , msg ); err != nil {
1536+ t .Errorf ("marshaler.Unmarshal(%q, msg) failed with %v; want success" , item .Result , err )
1537+ }
1538+ got = append (got , msg )
1539+ }
1540+
1541+ if invalidArgumentCount != 1 {
1542+ t .Errorf ("got %d errors with code 3; want exactly 1" , invalidArgumentCount )
1543+ }
1544+ }()
1545+
1546+ wg .Wait ()
1547+ if diff := cmp .Diff (got , want , protocmp .Transform ()); diff != "" {
1548+ t .Error (diff )
1549+ }
1550+ }
1551+
14511552func testAdditionalBindings (t * testing.T , port int ) {
14521553 for i , f := range []func () * http.Response {
14531554 func () * http.Response {
0 commit comments