| /* |
| * |
| * Copyright 2014, Google Inc. |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are |
| * met: |
| * |
| * * Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * * Redistributions in binary form must reproduce the above |
| * copyright notice, this list of conditions and the following disclaimer |
| * in the documentation and/or other materials provided with the |
| * distribution. |
| * * Neither the name of Google Inc. nor the names of its |
| * contributors may be used to endorse or promote products derived from |
| * this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| * |
| */ |
| |
| package transport |
| |
| import ( |
| "fmt" |
| "reflect" |
| "testing" |
| "time" |
| ) |
| |
| func TestTimeoutEncode(t *testing.T) { |
| for _, test := range []struct { |
| in string |
| out string |
| }{ |
| {"12345678ns", "12345678n"}, |
| {"123456789ns", "123457u"}, |
| {"12345678us", "12345678u"}, |
| {"123456789us", "123457m"}, |
| {"12345678ms", "12345678m"}, |
| {"123456789ms", "123457S"}, |
| {"12345678s", "12345678S"}, |
| {"123456789s", "2057614M"}, |
| {"12345678m", "12345678M"}, |
| {"123456789m", "2057614H"}, |
| } { |
| d, err := time.ParseDuration(test.in) |
| if err != nil { |
| t.Fatalf("failed to parse duration string %s: %v", test.in, err) |
| } |
| out := encodeTimeout(d) |
| if out != test.out { |
| t.Fatalf("timeoutEncode(%s) = %s, want %s", test.in, out, test.out) |
| } |
| } |
| } |
| |
| func TestTimeoutDecode(t *testing.T) { |
| for _, test := range []struct { |
| // input |
| s string |
| // output |
| d time.Duration |
| err error |
| }{ |
| {"1234S", time.Second * 1234, nil}, |
| {"1234x", 0, fmt.Errorf("transport: timeout unit is not recognized: %q", "1234x")}, |
| {"1", 0, fmt.Errorf("transport: timeout string is too short: %q", "1")}, |
| {"", 0, fmt.Errorf("transport: timeout string is too short: %q", "")}, |
| } { |
| d, err := decodeTimeout(test.s) |
| if d != test.d || fmt.Sprint(err) != fmt.Sprint(test.err) { |
| t.Fatalf("timeoutDecode(%q) = %d, %v, want %d, %v", test.s, int64(d), err, int64(test.d), test.err) |
| } |
| } |
| } |
| |
| func TestValidContentType(t *testing.T) { |
| tests := []struct { |
| h string |
| want bool |
| }{ |
| {"application/grpc", true}, |
| {"application/grpc+", true}, |
| {"application/grpc+blah", true}, |
| {"application/grpc;", true}, |
| {"application/grpc;blah", true}, |
| {"application/grpcd", false}, |
| {"application/grpd", false}, |
| {"application/grp", false}, |
| } |
| for _, tt := range tests { |
| got := validContentType(tt.h) |
| if got != tt.want { |
| t.Errorf("validContentType(%q) = %v; want %v", tt.h, got, tt.want) |
| } |
| } |
| } |
| |
| func TestEncodeGrpcMessage(t *testing.T) { |
| for _, tt := range []struct { |
| input string |
| expected string |
| }{ |
| {"", ""}, |
| {"Hello", "Hello"}, |
| {"my favorite character is \u0000", "my favorite character is %00"}, |
| {"my favorite character is %", "my favorite character is %25"}, |
| } { |
| actual := encodeGrpcMessage(tt.input) |
| if tt.expected != actual { |
| t.Errorf("encodeGrpcMessage(%v) = %v, want %v", tt.input, actual, tt.expected) |
| } |
| } |
| } |
| |
| func TestDecodeGrpcMessage(t *testing.T) { |
| for _, tt := range []struct { |
| input string |
| expected string |
| }{ |
| {"", ""}, |
| {"Hello", "Hello"}, |
| {"H%61o", "Hao"}, |
| {"H%6", "H%6"}, |
| {"%G0", "%G0"}, |
| {"%E7%B3%BB%E7%BB%9F", "系统"}, |
| } { |
| actual := decodeGrpcMessage(tt.input) |
| if tt.expected != actual { |
| t.Errorf("dncodeGrpcMessage(%v) = %v, want %v", tt.input, actual, tt.expected) |
| } |
| } |
| } |
| |
| const binaryValue = string(128) |
| |
| func TestEncodeMetadataHeader(t *testing.T) { |
| for _, test := range []struct { |
| // input |
| kin string |
| vin string |
| // output |
| vout string |
| }{ |
| {"key", "abc", "abc"}, |
| {"KEY", "abc", "abc"}, |
| {"key-bin", "abc", "YWJj"}, |
| {"key-bin", binaryValue, "woA"}, |
| } { |
| v := encodeMetadataHeader(test.kin, test.vin) |
| if !reflect.DeepEqual(v, test.vout) { |
| t.Fatalf("encodeMetadataHeader(%q, %q) = %q, want %q", test.kin, test.vin, v, test.vout) |
| } |
| } |
| } |
| |
| func TestDecodeMetadataHeader(t *testing.T) { |
| for _, test := range []struct { |
| // input |
| kin string |
| vin string |
| // output |
| vout string |
| err error |
| }{ |
| {"a", "abc", "abc", nil}, |
| {"key-bin", "Zm9vAGJhcg==", "foo\x00bar", nil}, |
| {"key-bin", "Zm9vAGJhcg", "foo\x00bar", nil}, |
| {"key-bin", "woA=", binaryValue, nil}, |
| {"a", "abc,efg", "abc,efg", nil}, |
| } { |
| v, err := decodeMetadataHeader(test.kin, test.vin) |
| if !reflect.DeepEqual(v, test.vout) || !reflect.DeepEqual(err, test.err) { |
| t.Fatalf("decodeMetadataHeader(%q, %q) = %q, %v, want %q, %v", test.kin, test.vin, v, err, test.vout, test.err) |
| } |
| } |
| } |