├── .github └── workflows │ └── tests.yaml ├── .gitignore ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE.md ├── Makefile ├── README.md ├── RELEASE.md ├── all_channels.go ├── all_channels_test.go ├── arguments.go ├── arguments_test.go ├── benchmark ├── benchclient │ └── main.go ├── benchserver │ └── main.go ├── build_manager.go ├── client_server_bench_test.go ├── external_client.go ├── external_common.go ├── external_server.go ├── frame_templates.go ├── interfaces.go ├── internal_client.go ├── internal_multi_client.go ├── internal_server.go ├── internal_tcp_client.go ├── internal_tcp_server.go ├── matrix_test.go ├── options.go ├── real_relay.go ├── req_bytes.go ├── tcp_bench_test.go ├── tcp_frame_relay.go └── tcp_raw_relay.go ├── calloptions.go ├── calloptions_test.go ├── channel.go ├── channel_test.go ├── channel_utils_test.go ├── channelstate_string.go ├── checked_frame_pool.go ├── checked_frame_pool_test.go ├── checksum.go ├── close_test.go ├── codecov.yml ├── conn_leak_test.go ├── connection.go ├── connection_bench_test.go ├── connection_direction.go ├── connection_internal_test.go ├── connection_test.go ├── connectionstate_string.go ├── context.go ├── context_builder.go ├── context_header.go ├── context_internal_test.go ├── context_test.go ├── crossdock ├── .gitignore ├── Dockerfile ├── behavior │ └── trace │ │ ├── api.go │ │ ├── behavior.go │ │ ├── behavior_test.go │ │ ├── constants.go │ │ ├── json.go │ │ └── thrift.go ├── client │ ├── client.go │ └── client_test.go ├── common │ └── constants.go ├── docker-compose.yml ├── log │ └── logging.go ├── main.go ├── rules.mk └── server │ ├── server.go │ └── server_test.go ├── deps_test.go ├── dial_16.go ├── dial_17.go ├── dial_17_test.go ├── doc.go ├── errors.go ├── errors_test.go ├── examples ├── bench │ ├── client │ │ └── client.go │ ├── runner.go │ └── server │ │ └── server.go ├── hyperbahn │ └── echo-server │ │ └── main.go ├── hypercat │ └── main.go ├── keyvalue │ ├── README.md │ ├── client │ │ └── client.go │ ├── gen-go │ │ └── keyvalue │ │ │ ├── admin.go │ │ │ ├── baseservice.go │ │ │ ├── constants.go │ │ │ ├── keyvalue.go │ │ │ ├── tchan-keyvalue.go │ │ │ └── ttypes.go │ ├── keyvalue.thrift │ └── server │ │ └── server.go ├── ping │ ├── README.md │ └── main.go ├── test_server │ └── server.go └── thrift │ ├── example.thrift │ ├── gen-go │ └── example │ │ ├── base.go │ │ ├── constants.go │ │ ├── first.go │ │ ├── second.go │ │ ├── tchan-example.go │ │ └── ttypes.go │ └── main.go ├── fragmentation_test.go ├── fragmenting_reader.go ├── fragmenting_writer.go ├── frame.go ├── frame_pool.go ├── frame_pool_b_test.go ├── frame_pool_test.go ├── frame_test.go ├── frame_utils_test.go ├── go.mod ├── go.sum ├── guide └── Thrift_Hyperbahn.md ├── handlers.go ├── handlers_test.go ├── handlers_with_skip_test.go ├── health.go ├── health_ext_test.go ├── health_test.go ├── http ├── buf.go ├── buf_test.go ├── http_test.go ├── request.go └── response.go ├── hyperbahn ├── advertise.go ├── advertise_test.go ├── call.go ├── client.go ├── client_test.go ├── configuration.go ├── discover.go ├── discover_test.go ├── event_string.go ├── events.go ├── gen-go │ └── hyperbahn │ │ ├── constants.go │ │ ├── hyperbahn.go │ │ ├── tchan-hyperbahn.go │ │ └── ttypes.go ├── hyperbahn.thrift ├── utils.go └── utils_test.go ├── idle_sweep.go ├── idle_sweep_test.go ├── inbound.go ├── inbound_internal_test.go ├── inbound_test.go ├── incoming_test.go ├── init_test.go ├── internal ├── argreader │ ├── empty.go │ └── empty_test.go └── testcert │ └── testcert.go ├── introspection.go ├── introspection_test.go ├── json ├── call.go ├── context.go ├── handler.go ├── json_test.go ├── retry_test.go └── tracing_test.go ├── largereq_test.go ├── localip.go ├── localip_test.go ├── logger.go ├── logger_test.go ├── messages.go ├── messages_test.go ├── messagetype_string.go ├── mex.go ├── mex_utils_test.go ├── outbound.go ├── peer.go ├── peer_bench_test.go ├── peer_heap.go ├── peer_heap_test.go ├── peer_internal_test.go ├── peer_strategies.go ├── peer_test.go ├── peers ├── doc.go ├── prefer.go └── prefer_test.go ├── pprof ├── pprof.go └── pprof_test.go ├── preinit_connection.go ├── raw ├── call.go └── handler.go ├── relay.go ├── relay ├── relay.go └── relaytest │ ├── func_host.go │ ├── mock_stats.go │ └── stub_host.go ├── relay_api.go ├── relay_benchmark_test.go ├── relay_fragment_sender_test.go ├── relay_internal_test.go ├── relay_messages.go ├── relay_messages_benchmark_test.go ├── relay_messages_test.go ├── relay_test.go ├── relay_timer_pool.go ├── reqres.go ├── reqresreaderstate_string.go ├── reqreswriterstate_string.go ├── retry.go ├── retry_request_test.go ├── retry_test.go ├── retryon_string.go ├── root_peer_list.go ├── scripts ├── install-thrift.sh └── vbumper │ └── main.go ├── sockio_bsd.go ├── sockio_darwin.go ├── sockio_linux.go ├── sockio_non_unix.go ├── sockio_unix.go ├── stats.go ├── stats ├── metrickey.go ├── metrickey_test.go ├── statsdreporter.go ├── tally.go └── tally_test.go ├── stats_test.go ├── stats_utils_test.go ├── stream_test.go ├── stress_flag_test.go ├── subchannel.go ├── subchannel_test.go ├── systemerrcode_string.go ├── tchannel_test.go ├── testutils ├── call.go ├── channel.go ├── channel_opts.go ├── channel_t.go ├── conn.go ├── counter.go ├── counter_test.go ├── data.go ├── echo.go ├── goroutines │ ├── stacks.go │ ├── verify.go │ └── verify_opts.go ├── lists.go ├── logfilter_test.go ├── logger.go ├── mockhyperbahn │ ├── hyperbahn.go │ ├── hyperbahn_test.go │ └── utils.go ├── now.go ├── random_bench_test.go ├── relay.go ├── sleep.go ├── test_server.go ├── testreader │ ├── chunk.go │ ├── chunk_test.go │ ├── loop.go │ └── loop_test.go ├── testtracing │ ├── propagation.go │ └── propagation_test.go ├── testwriter │ ├── limited.go │ └── limited_test.go ├── thriftarg2test │ ├── arg2_kv.go │ └── arg2_kv_test.go ├── ticker.go ├── ticker_test.go ├── timeout.go └── wait.go ├── thirdparty └── github.com │ └── apache │ └── thrift │ └── lib │ └── go │ └── thrift │ ├── application_exception.go │ ├── application_exception_test.go │ ├── binary_protocol.go │ ├── binary_protocol_test.go │ ├── buffered_transport.go │ ├── buffered_transport_test.go │ ├── compact_protocol.go │ ├── compact_protocol_test.go │ ├── debug_protocol.go │ ├── deserializer.go │ ├── exception.go │ ├── exception_test.go │ ├── field.go │ ├── framed_transport.go │ ├── framed_transport_test.go │ ├── http_client.go │ ├── http_client_test.go │ ├── http_transport.go │ ├── iostream_transport.go │ ├── iostream_transport_test.go │ ├── json_protocol.go │ ├── json_protocol_test.go │ ├── lowlevel_benchmarks_test.go │ ├── memory_buffer.go │ ├── memory_buffer_test.go │ ├── messagetype.go │ ├── multiplexed_protocol.go │ ├── numeric.go │ ├── pointerize.go │ ├── processor.go │ ├── processor_factory.go │ ├── protocol.go │ ├── protocol_exception.go │ ├── protocol_factory.go │ ├── protocol_test.go │ ├── rich_transport.go │ ├── rich_transport_test.go │ ├── serializer.go │ ├── serializer_test.go │ ├── serializer_types_test.go │ ├── server.go │ ├── server_socket.go │ ├── server_socket_test.go │ ├── server_test.go │ ├── server_transport.go │ ├── simple_json_protocol.go │ ├── simple_json_protocol_test.go │ ├── simple_server.go │ ├── socket.go │ ├── ssl_server_socket.go │ ├── ssl_socket.go │ ├── transport.go │ ├── transport_exception.go │ ├── transport_exception_test.go │ ├── transport_factory.go │ ├── transport_test.go │ ├── type.go │ ├── zlib_transport.go │ └── zlib_transport_test.go ├── thrift ├── arg2 │ ├── kv_iterator.go │ └── kv_iterator_test.go ├── client.go ├── context.go ├── context_test.go ├── doc.go ├── errors_test.go ├── gen-go │ ├── meta │ │ ├── constants.go │ │ ├── meta.go │ │ └── ttypes.go │ └── test │ │ ├── constants.go │ │ ├── meta.go │ │ ├── secondservice.go │ │ ├── simpleservice.go │ │ ├── tchan-test.go │ │ └── ttypes.go ├── headers.go ├── headers_test.go ├── interfaces.go ├── meta.go ├── meta.thrift ├── meta_test.go ├── mocks │ ├── TChanMeta.go │ ├── TChanSecondService.go │ └── TChanSimpleService.go ├── options.go ├── server.go ├── server_test.go ├── struct.go ├── struct_test.go ├── tchan-meta.go ├── test.thrift ├── thrift-gen │ ├── compile_test.go │ ├── extends.go │ ├── generate.go │ ├── gopath.go │ ├── gopath_test.go │ ├── include.go │ ├── main.go │ ├── names.go │ ├── tchannel-template.go │ ├── template.go │ ├── test_files │ │ ├── binary.thrift │ │ ├── byte.thrift │ │ ├── gokeywords.thrift │ │ ├── include_test │ │ │ ├── namespace │ │ │ │ ├── a │ │ │ │ │ └── shared.thrift │ │ │ │ ├── b │ │ │ │ │ └── shared.thrift │ │ │ │ └── namespace.thrift │ │ │ ├── simple │ │ │ │ ├── shared.thrift │ │ │ │ ├── shared2.thrift │ │ │ │ └── simple.thrift │ │ │ └── svc_extend │ │ │ │ ├── shared.thrift │ │ │ │ └── svc_extend.thrift │ │ ├── multi_test │ │ │ ├── file1.thrift │ │ │ └── file2.thrift │ │ ├── service_extend.thrift │ │ ├── sets.thrift │ │ ├── test1.thrift │ │ ├── typedefs.thrift │ │ └── union.thrift │ ├── typestate.go │ ├── validate.go │ └── wrap.go ├── thrift_bench_test.go ├── thrift_test.go ├── tracing_test.go ├── transport.go └── transport_test.go ├── tnet ├── listener.go └── listener_test.go ├── tos ├── tos.go ├── tos_string.go └── tos_test.go ├── trace └── doc.go ├── tracing.go ├── tracing_internal_test.go ├── tracing_keys.go ├── tracing_test.go ├── trand └── rand.go ├── typed ├── buffer.go ├── buffer_test.go ├── reader.go ├── reader_test.go ├── writer.go └── writer_test.go ├── utils_for_test.go ├── verify_utils_test.go └── version.go /.github/workflows/tests.yaml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | 3 | on: 4 | push: 5 | branches: ['*'] 6 | tags: ['v*'] 7 | pull_request: 8 | branches: ['**'] 9 | 10 | jobs: 11 | test: 12 | runs-on: ubuntu-latest 13 | env: 14 | GOPATH: ${{ github.workspace }} 15 | GOBIN: ${{ github.workspace }}/bin 16 | defaults: 17 | run: 18 | working-directory: ${{ env.GOPATH }}/src/github.com/${{ github.repository }} 19 | strategy: 20 | matrix: 21 | go: ["stable", "oldstable"] 22 | include: 23 | - go: "stable" 24 | latest: true 25 | COVERAGE: "yes" 26 | LINT: "yes" 27 | - go: "oldstable" 28 | LINT: "yes" 29 | 30 | steps: 31 | - name: Setup Go 32 | uses: actions/setup-go@v5 33 | with: 34 | go-version: ${{ matrix.go }} 35 | 36 | - name: Checkout code 37 | uses: actions/checkout@v2 38 | with: 39 | path: ${{ env.GOPATH }}/src/github.com/${{ github.repository }} 40 | 41 | - name: Load cache 42 | uses: actions/cache@v1 43 | with: 44 | path: ~/.glide/cache 45 | key: ${{ runner.os }}-go-${{ hashFiles('**/glide.lock') }} 46 | restore-keys: | 47 | ${{ runner.os }}-go- 48 | 49 | - name: Install CI 50 | run: make install_ci 51 | 52 | - name: Test CI 53 | env: 54 | NO_TEST: ${{ matrix.NO_TEST }} 55 | run: test -n "$NO_TEST" || make test_ci 56 | 57 | - name: Cover CI 58 | env: 59 | COVERAGE: ${{ matrix.COVERAGE }} 60 | run: test -z "$COVERAGE" || make cover_ci 61 | 62 | - name: Lint CI 63 | env: 64 | LINT: ${{ matrix.LINT }} 65 | run: test -z "$LINT" || make install_lint lint 66 | 67 | - name: Crossdock CI 68 | run: make crossdock_logs_ci 69 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | Godeps/_workspace 3 | vendor/ 4 | thrift-gen-release/ 5 | 6 | # Lint output 7 | lint.log 8 | 9 | # Cover profiles 10 | *.out 11 | 12 | # Editor and OS detritus 13 | *~ 14 | *.swp 15 | .DS_Store 16 | .idea 17 | tchannel-go.iml 18 | .vscode 19 | .bin/ 20 | .idea/ 21 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contributing 2 | ============ 3 | 4 | We'd love your help making tchannel-go great! 5 | 6 | ## Getting Started 7 | 8 | TChannel uses [glide](https://github.com/Masterminds/glide) to manage 9 | dependencies. 10 | To get started: 11 | 12 | ```bash 13 | go get github.com/uber/tchannel-go 14 | make install_glide 15 | make # tests should pass 16 | ``` 17 | 18 | ## Making A Change 19 | 20 | *Before making any significant changes, please [open an 21 | issue](https://github.com/uber/tchannel-go/issues).* Discussing your proposed 22 | changes ahead of time will make the contribution process smooth for everyone. 23 | 24 | Once we've discussed your changes and you've got your code ready, make sure 25 | that tests are passing (`make test` or `make cover`) and open your PR! Your 26 | pull request is most likely to be accepted if it: 27 | 28 | * Includes tests for new functionality. 29 | * Follows the guidelines in [Effective 30 | Go](https://golang.org/doc/effective_go.html) and the [Go team's common code 31 | review comments](https://github.com/golang/go/wiki/CodeReviewComments). 32 | * Has a [good commit 33 | message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html). 34 | 35 | ## Cutting a Release 36 | 37 | * Send a pull request against dev including: 38 | * update CHANGELOG.md (`scripts/changelog_halp.sh`) 39 | * update version.go 40 | * Send a pull request for dev into master 41 | * `git tag -m v0.0.0 -a v0.0.0` 42 | * `git push origin --tags` 43 | * Copy CHANGELOG.md fragment into release notes on 44 | https://github.com/uber/tchannel-go/releases 45 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /RELEASE.md: -------------------------------------------------------------------------------- 1 | Release process 2 | =============== 3 | 4 | This document outlines how to create a release of tchannel-go 5 | 6 | 1. Set up some environment variables for use later. 7 | 8 | ``` 9 | # This is the version being released. 10 | $ VERSION=1.8.0 11 | ``` 12 | 13 | 2. Make sure you have the latest dev and create a branch off it. 14 | 15 | ``` 16 | $ git checkout dev 17 | $ git pull 18 | $ git checkout -b release 19 | ``` 20 | 21 | 3. Update the `CHANGELOG.md` and `version.go` files. 22 | 23 | ``` 24 | $ go run ./scripts/vbumper/main.go --version $VERSION 25 | ``` 26 | 27 | 4. Clean up the `CHANGELOG.md` to only mention noteworthy changes for users. 28 | 29 | 5. Commit changes and create a PR against `dev` to prepare for release. 30 | 31 | 6. Once the release PR has been accepted, run the following to release. 32 | 33 | ``` 34 | $ git checkout master 35 | $ git pull 36 | $ git merge dev 37 | $ git tag -a "v$VERSION" -m "v$VERSION" 38 | $ git push origin master v$VERSION 39 | ``` 40 | 41 | 7. Go to and edit the release notes. 42 | Copy changelog entries for this release and set the name to `v$VERSION`. 43 | 44 | 8. Switch back to development. 45 | 46 | ``` 47 | $ git checkout dev 48 | $ git merge master 49 | $ go run ./scripts/vbumper/main.go --version ${VERSION}-dev --skip-changelog 50 | $ git commit -am "Back to development" 51 | $ git push 52 | ``` 53 | -------------------------------------------------------------------------------- /benchmark/build_manager.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package benchmark 22 | 23 | import ( 24 | "io/ioutil" 25 | "os" 26 | "os/exec" 27 | "sync" 28 | ) 29 | 30 | type buildManager struct { 31 | sync.RWMutex 32 | builds map[string]*build 33 | } 34 | 35 | type build struct { 36 | once sync.Once 37 | mainFile string 38 | 39 | binaryFile string 40 | buildErr error 41 | } 42 | 43 | func newBuildManager() *buildManager { 44 | return &buildManager{ 45 | builds: make(map[string]*build), 46 | } 47 | } 48 | 49 | func (m *buildManager) GoBinary(mainFile string) (string, error) { 50 | m.Lock() 51 | bld, ok := m.builds[mainFile] 52 | if !ok { 53 | bld = &build{mainFile: mainFile} 54 | m.builds[mainFile] = bld 55 | } 56 | m.Unlock() 57 | 58 | bld.once.Do(bld.Build) 59 | return bld.binaryFile, bld.buildErr 60 | } 61 | 62 | func (b *build) Build() { 63 | tempFile, err := ioutil.TempFile("", "bench") 64 | if err != nil { 65 | panic("Failed to create temp file: " + err.Error()) 66 | } 67 | tempFile.Close() 68 | 69 | buildCmd := exec.Command("go", "build", "-o", tempFile.Name(), b.mainFile) 70 | buildCmd.Stdout = os.Stdout 71 | buildCmd.Stderr = os.Stderr 72 | if err := buildCmd.Run(); err != nil { 73 | b.buildErr = err 74 | return 75 | } 76 | 77 | b.binaryFile = tempFile.Name() 78 | } 79 | -------------------------------------------------------------------------------- /benchmark/req_bytes.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package benchmark 22 | 23 | func getRequestBytes(n int) []byte { 24 | bs := make([]byte, n) 25 | for i := range bs { 26 | bs[i] = byte(i) 27 | } 28 | return bs 29 | } 30 | 31 | func getRequestString(n int) string { 32 | // TODO: we should replace this with base64 once we drop go1.4 support. 33 | chars := []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZabcedefghijklmnopqrstuvwxyz") 34 | bs := make([]byte, n) 35 | for i := range bs { 36 | bs[i] = chars[i%len(chars)] 37 | } 38 | return string(bs) 39 | } 40 | -------------------------------------------------------------------------------- /channel_utils_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package tchannel_test 22 | 23 | import ( 24 | "testing" 25 | 26 | . "github.com/uber/tchannel-go" 27 | 28 | "github.com/uber/tchannel-go/testutils" 29 | ) 30 | 31 | // NewServer creates a new server and returns the channel, service name, and host port. 32 | func NewServer(t testing.TB, opts *testutils.ChannelOpts) (*Channel, string, string) { 33 | ch := testutils.NewServer(t, opts) 34 | peerInfo := ch.PeerInfo() 35 | return ch, peerInfo.ServiceName, peerInfo.HostPort 36 | } 37 | -------------------------------------------------------------------------------- /channelstate_string.go: -------------------------------------------------------------------------------- 1 | // generated by stringer -type=ChannelState; DO NOT EDIT 2 | 3 | package tchannel 4 | 5 | import "fmt" 6 | 7 | const _ChannelState_name = "ChannelClientChannelListeningChannelStartCloseChannelInboundClosedChannelClosed" 8 | 9 | var _ChannelState_index = [...]uint8{0, 13, 29, 46, 66, 79} 10 | 11 | func (i ChannelState) String() string { 12 | i -= 1 13 | if i < 0 || i+1 >= ChannelState(len(_ChannelState_index)) { 14 | return fmt.Sprintf("ChannelState(%d)", i+1) 15 | } 16 | return _ChannelState_name[_ChannelState_index[i]:_ChannelState_index[i+1]] 17 | } 18 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | coverage: 2 | range: 75..100 3 | round: down 4 | precision: 2 5 | 6 | status: 7 | project: 8 | default: 9 | enabled: yes 10 | target: 85% 11 | if_not_found: success 12 | if_ci_failed: error 13 | ignore: 14 | - "*_string.go" 15 | 16 | -------------------------------------------------------------------------------- /connection_direction.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package tchannel 22 | 23 | import "fmt" 24 | 25 | type connectionDirection int 26 | 27 | const ( 28 | inbound connectionDirection = iota + 1 29 | outbound 30 | ) 31 | 32 | func (d connectionDirection) String() string { 33 | switch d { 34 | case inbound: 35 | return "inbound" 36 | case outbound: 37 | return "outbound" 38 | default: 39 | return fmt.Sprintf("connectionDirection(%v)", int(d)) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /connectionstate_string.go: -------------------------------------------------------------------------------- 1 | // Code generated by "stringer -type=connectionState"; DO NOT EDIT 2 | 3 | package tchannel 4 | 5 | import "fmt" 6 | 7 | const _connectionState_name = "connectionActiveconnectionStartCloseconnectionInboundClosedconnectionClosed" 8 | 9 | var _connectionState_index = [...]uint8{0, 16, 36, 59, 75} 10 | 11 | func (i connectionState) String() string { 12 | i -= 1 13 | if i < 0 || i >= connectionState(len(_connectionState_index)-1) { 14 | return fmt.Sprintf("connectionState(%d)", i+1) 15 | } 16 | return _connectionState_name[_connectionState_index[i]:_connectionState_index[i+1]] 17 | } 18 | -------------------------------------------------------------------------------- /crossdock/.gitignore: -------------------------------------------------------------------------------- 1 | /crossdock 2 | -------------------------------------------------------------------------------- /crossdock/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang 2 | ADD crossdock / 3 | CMD ["/crossdock"] 4 | EXPOSE 8080-8082 5 | -------------------------------------------------------------------------------- /crossdock/behavior/trace/api.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package trace 22 | 23 | // Request instructs the server to call another server recursively if Downstream != nil, 24 | // and return the results of the downstream call as well as the current tracing span it 25 | // observes in its Context. 26 | type Request struct { 27 | ServerRole string `json:"serverRole"` 28 | Downstream *Downstream `json:"downstream,omitempty"` 29 | } 30 | 31 | // Downstream describes which downstream service to call recursively. 32 | type Downstream struct { 33 | ServiceName string `json:"serviceName"` 34 | ServerRole string `json:"serverRole"` 35 | Encoding string `json:"encoding"` 36 | HostPort string `json:"hostPort"` 37 | Downstream *Downstream `json:"downstream,omitempty"` 38 | } 39 | 40 | // Response contains the span observed by the server and nested downstream response. 41 | type Response struct { 42 | Span *ObservedSpan `json:"span,omitempty"` 43 | Downstream *Response `json:"downstream,omitempty"` 44 | } 45 | 46 | // ObservedSpan describes the tracing span observed by the server 47 | type ObservedSpan struct { 48 | TraceID string `json:"traceId"` 49 | Sampled bool `json:"sampled"` 50 | Baggage string `json:"baggage"` 51 | } 52 | -------------------------------------------------------------------------------- /crossdock/behavior/trace/constants.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package trace 22 | 23 | import "errors" 24 | 25 | const ( 26 | // S1 instructions 27 | sampledParam = "sampled" 28 | server1NameParam = "s1name" 29 | 30 | // S1->S2 instructions 31 | server2NameParam = "s2name" 32 | server2EncodingParam = "s2encoding" 33 | 34 | // S2->S3 instructions 35 | server3NameParam = "s3name" 36 | server3EncodingParam = "s3encoding" 37 | 38 | // RoleS1 is the name of the role for server S1 39 | RoleS1 = "S1" 40 | 41 | // RoleS2 is the name of the role for server S2 42 | RoleS2 = "S2" 43 | 44 | // RoleS3 is the name of the role for server S3 45 | RoleS3 = "S3" 46 | 47 | // BaggageKey is the key used to pass baggage item 48 | BaggageKey = "crossdock-baggage-key" 49 | ) 50 | 51 | var ( 52 | errNoSpanObserved = errors.New("no span found in Context") 53 | errUnsupportedEncoding = errors.New("unsupported encoding for downstream call") 54 | ) 55 | -------------------------------------------------------------------------------- /crossdock/common/constants.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package common 22 | 23 | const ( 24 | // DefaultClientPortHTTP is the port where the client (controller) runs 25 | DefaultClientPortHTTP = "8080" 26 | 27 | // DefaultServerPort is the port of TChannel server 28 | DefaultServerPort = "8081" 29 | 30 | // DefaultServiceName is the service name used by TChannel server 31 | DefaultServiceName = "go" 32 | ) 33 | -------------------------------------------------------------------------------- /crossdock/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | 3 | services: 4 | crossdock: 5 | image: crossdock/crossdock 6 | links: 7 | - go 8 | - python 9 | environment: 10 | - WAIT_FOR=go 11 | 12 | - AXIS_CLIENT=go 13 | - AXIS_S1NAME=go 14 | - AXIS_SAMPLED=true,false 15 | - AXIS_S2NAME=go,python 16 | - AXIS_S2ENCODING=json,thrift 17 | - AXIS_S3NAME=go,python 18 | - AXIS_S3ENCODING=json,thrift 19 | 20 | - BEHAVIOR_TRACE=client,s1name,sampled,s2name,s2encoding,s3name,s3encoding 21 | 22 | go: 23 | build: . 24 | ports: 25 | - "8080-8082" 26 | 27 | python: 28 | image: tchannelhub/xdock-py 29 | ports: 30 | - "8080-8082" 31 | -------------------------------------------------------------------------------- /crossdock/log/logging.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package log 22 | 23 | import ( 24 | stdlog "log" 25 | ) 26 | 27 | // Enabled controls logging 28 | var Enabled = false 29 | 30 | // Println is the equivalent of standard log.Println gated by Enabled flag 31 | func Println(msg string) { 32 | if Enabled { 33 | stdlog.Println(msg) 34 | } 35 | } 36 | 37 | // Printf is the equivalent of standard log.Printf gated by Enabled flag 38 | func Printf(format string, v ...interface{}) { 39 | if Enabled { 40 | stdlog.Printf(format, v...) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /crossdock/rules.mk: -------------------------------------------------------------------------------- 1 | XDOCK_YAML=crossdock/docker-compose.yml 2 | 3 | .PHONY: crossdock-linux-bin 4 | crossdock-linux-bin: 5 | CGO_ENABLED=0 GOOS=linux time go build -a -installsuffix cgo -o crossdock/crossdock ./crossdock 6 | 7 | .PHONY: crossdock 8 | crossdock: crossdock-linux-bin 9 | docker-compose -f $(XDOCK_YAML) kill go 10 | docker-compose -f $(XDOCK_YAML) rm -f go 11 | docker-compose -f $(XDOCK_YAML) build go 12 | docker-compose -f $(XDOCK_YAML) run crossdock 13 | 14 | 15 | .PHONY: crossdock-fresh 16 | crossdock-fresh: crossdock-linux-bin 17 | docker-compose -f $(XDOCK_YAML) kill 18 | docker-compose -f $(XDOCK_YAML) rm --force 19 | docker-compose -f $(XDOCK_YAML) pull 20 | docker-compose -f $(XDOCK_YAML) build 21 | docker-compose -f $(XDOCK_YAML) run crossdock 22 | 23 | .PHONY: crossdock-logs 24 | crossdock-logs: 25 | docker-compose -f $(XDOCK_YAML) logs 26 | 27 | .PHONY: install_docker_ci 28 | install_docker_ci: 29 | @echo "Installing docker-compose $${DOCKER_COMPOSE_VERSION:?'DOCKER_COMPOSE_VERSION env not set'}" 30 | sudo rm -f /usr/local/bin/docker-compose 31 | curl -L https://github.com/docker/compose/releases/download/$${DOCKER_COMPOSE_VERSION}/docker-compose-`uname -s`-`uname -m` > docker-compose 32 | chmod +x docker-compose 33 | sudo mv docker-compose /usr/local/bin 34 | docker-compose version 35 | 36 | .PHONY: crossdock_ci 37 | crossdock_ci: 38 | ifdef CROSSDOCK 39 | docker version 40 | $(MAKE) crossdock 41 | else 42 | true 43 | endif 44 | 45 | .PHONY: crossdock_logs_ci 46 | crossdock_logs_ci: 47 | ifdef CROSSDOCK 48 | docker-compose -f $(XDOCK_YAML) logs 49 | else 50 | true 51 | endif 52 | 53 | -------------------------------------------------------------------------------- /crossdock/server/server_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package server 22 | 23 | import ( 24 | "strconv" 25 | "testing" 26 | 27 | "github.com/opentracing/opentracing-go/mocktracer" 28 | "github.com/stretchr/testify/assert" 29 | "github.com/stretchr/testify/require" 30 | ) 31 | 32 | func TestServer(t *testing.T) { 33 | tracer := mocktracer.New() 34 | 35 | s := &Server{HostPort: "127.0.0.1:0", Tracer: tracer} 36 | err := s.Start() 37 | require.NoError(t, err) 38 | defer s.Close() 39 | 40 | assert.Equal(t, tracer, s.Ch.Tracer()) 41 | port, err := strconv.Atoi(s.Port()) 42 | assert.NoError(t, err) 43 | assert.True(t, port > 0) 44 | } 45 | 46 | func TestServerErrors(t *testing.T) { 47 | s := &Server{HostPort: "127.0.0.1:xxx"} 48 | err := s.Start() 49 | require.Error(t, err) 50 | } 51 | -------------------------------------------------------------------------------- /deps_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | // Our glide.yaml lists a set of directories in excludeDirs to avoid packages 22 | // only used in testing from pulling in dependencies that should not affect 23 | // package resolution for clients. 24 | // However, we really want these directories to be part of test imports. Since 25 | // glide does not provide a "testDirs" option, we add dependencies required 26 | // for tests in this _test.go file. 27 | 28 | package tchannel_test 29 | 30 | import ( 31 | "testing" 32 | 33 | jcg "github.com/uber/jaeger-client-go" 34 | ) 35 | 36 | func TestJaegerDeps(t *testing.T) { 37 | m := jcg.Metrics{} 38 | _ = m.SamplerUpdateFailure 39 | } 40 | -------------------------------------------------------------------------------- /dial_16.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | //go:build !go1.7 22 | // +build !go1.7 23 | 24 | package tchannel 25 | 26 | import ( 27 | "net" 28 | 29 | "golang.org/x/net/context" 30 | ) 31 | 32 | func dialContext(ctx context.Context, hostPort string) (net.Conn, error) { 33 | timeout := getTimeout(ctx) 34 | return net.DialTimeout("tcp", hostPort, timeout) 35 | } 36 | -------------------------------------------------------------------------------- /dial_17.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | //go:build go1.7 22 | // +build go1.7 23 | 24 | package tchannel 25 | 26 | import ( 27 | "context" 28 | "net" 29 | ) 30 | 31 | func dialContext(ctx context.Context, hostPort string) (net.Conn, error) { 32 | d := net.Dialer{} 33 | return d.DialContext(ctx, "tcp", hostPort) 34 | } 35 | -------------------------------------------------------------------------------- /doc.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | /* 22 | Package tchannel implements Go bindings for the TChannel protocol (https://github.com/uber/tchannel). 23 | 24 | A single Channel can be used for many concurrent requests to many hosts. 25 | */ 26 | package tchannel 27 | -------------------------------------------------------------------------------- /examples/keyvalue/README.md: -------------------------------------------------------------------------------- 1 | # Key-Value Store 2 | 3 | ```bash 4 | ./build/examples/keyvalue/server 5 | ./build/examples/keyvalue/client 6 | ``` 7 | 8 | This example exposes a simple key-value store over TChannel using the Thrift 9 | protocol. The client has an interactive CLI that can be used to make calls to 10 | the server. 11 | -------------------------------------------------------------------------------- /examples/keyvalue/gen-go/keyvalue/constants.go: -------------------------------------------------------------------------------- 1 | // Autogenerated by Thrift Compiler (1.0.0-dev) 2 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 3 | 4 | package keyvalue 5 | 6 | import ( 7 | "bytes" 8 | "fmt" 9 | "github.com/uber/tchannel-go/thirdparty/github.com/apache/thrift/lib/go/thrift" 10 | ) 11 | 12 | // (needed to ensure safety because of naive import list construction.) 13 | var _ = thrift.ZERO 14 | var _ = fmt.Printf 15 | var _ = bytes.Equal 16 | 17 | func init() { 18 | } 19 | -------------------------------------------------------------------------------- /examples/keyvalue/keyvalue.thrift: -------------------------------------------------------------------------------- 1 | service baseService { 2 | string HealthCheck() 3 | } 4 | 5 | exception KeyNotFound { 6 | 1: string key 7 | } 8 | 9 | exception InvalidKey {} 10 | 11 | service KeyValue extends baseService { 12 | // If the key does not start with a letter, InvalidKey is returned. 13 | // If the key does not exist, KeyNotFound is returned. 14 | string Get(1: string key) throws ( 15 | 1: KeyNotFound notFound 16 | 2: InvalidKey invalidKey) 17 | 18 | // Set returns InvalidKey is an invalid key is sent. 19 | void Set(1: string key, 2: string value) throws ( 20 | 1: InvalidKey invalidKey 21 | ) 22 | } 23 | 24 | // Returned when the user is not authorized for the Admin service. 25 | exception NotAuthorized {} 26 | 27 | service Admin extends baseService { 28 | void clearAll() throws (1: NotAuthorized notAuthorized) 29 | } 30 | -------------------------------------------------------------------------------- /examples/ping/README.md: -------------------------------------------------------------------------------- 1 | # Ping-Pong 2 | 3 | ```bash 4 | ./build/examples/ping/pong 5 | ``` 6 | 7 | This example creates a client and server channel. The server channel registers 8 | a `PingService` with a `ping` method, which takes request `Headers` and a `Ping` body 9 | and returns the same `Headers` along with a `Pong` body. The client sends a ping 10 | request to the server. 11 | 12 | Note that every instance is bidirectional, so the same channel can be used for 13 | both sending and receiving requests to peers. New connections are initiated on 14 | demand. 15 | -------------------------------------------------------------------------------- /examples/test_server/server.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "flag" 25 | "fmt" 26 | "log" 27 | 28 | "golang.org/x/net/context" 29 | 30 | "github.com/uber/tchannel-go" 31 | "github.com/uber/tchannel-go/raw" 32 | ) 33 | 34 | var ( 35 | flagHost = flag.String("host", "localhost", "The hostname to serve on") 36 | flagPort = flag.Int("port", 0, "The port to listen on") 37 | ) 38 | 39 | type rawHandler struct{} 40 | 41 | func (rawHandler) Handle(ctx context.Context, args *raw.Args) (*raw.Res, error) { 42 | return &raw.Res{ 43 | Arg2: args.Arg2, 44 | Arg3: args.Arg3, 45 | }, nil 46 | } 47 | 48 | func (rawHandler) OnError(ctx context.Context, err error) { 49 | log.Fatalf("OnError: %v", err) 50 | } 51 | 52 | func main() { 53 | flag.Parse() 54 | 55 | ch, err := tchannel.NewChannel("test_as_raw", nil) 56 | if err != nil { 57 | log.Fatalf("NewChannel failed: %v", err) 58 | } 59 | 60 | handler := raw.Wrap(rawHandler{}) 61 | ch.Register(handler, "echo") 62 | ch.Register(handler, "streaming_echo") 63 | 64 | hostPort := fmt.Sprintf("%s:%v", *flagHost, *flagPort) 65 | if err := ch.ListenAndServe(hostPort); err != nil { 66 | log.Fatalf("ListenAndServe failed: %v", err) 67 | } 68 | 69 | fmt.Println("listening on", ch.PeerInfo().HostPort) 70 | select {} 71 | } 72 | -------------------------------------------------------------------------------- /examples/thrift/example.thrift: -------------------------------------------------------------------------------- 1 | struct HealthCheckRes { 2 | 1: bool healthy, 3 | 2: string msg, 4 | } 5 | 6 | service Base { 7 | void BaseCall() 8 | } 9 | 10 | service First extends Base { 11 | string Echo(1:string msg) 12 | HealthCheckRes Healthcheck() 13 | void AppError() 14 | } 15 | 16 | service Second { 17 | void Test() 18 | } 19 | -------------------------------------------------------------------------------- /examples/thrift/gen-go/example/constants.go: -------------------------------------------------------------------------------- 1 | // Autogenerated by Thrift Compiler (1.0.0-dev) 2 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 3 | 4 | package example 5 | 6 | import ( 7 | "bytes" 8 | "fmt" 9 | "github.com/uber/tchannel-go/thirdparty/github.com/apache/thrift/lib/go/thrift" 10 | ) 11 | 12 | // (needed to ensure safety because of naive import list construction.) 13 | var _ = thrift.ZERO 14 | var _ = fmt.Printf 15 | var _ = bytes.Equal 16 | 17 | func init() { 18 | } 19 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/uber/tchannel-go 2 | 3 | go 1.21 4 | 5 | require ( 6 | github.com/HdrHistogram/hdrhistogram-go v0.9.0 // indirect 7 | github.com/bmizerany/perks v0.0.0-20141205001514-d9a9656a3a4b 8 | github.com/cactus/go-statsd-client/statsd v0.0.0-20190922033735-5ca90424ceb7 9 | github.com/crossdock/crossdock-go v0.0.0-20160816171116-049aabb0122b 10 | github.com/jessevdk/go-flags v1.4.0 11 | github.com/opentracing/opentracing-go v1.1.0 12 | github.com/prashantv/protectmem v0.0.0-20171002184600-e20412882b3a 13 | github.com/samuel/go-thrift v0.0.0-20190219015601-e8b6b52668fe 14 | github.com/streadway/quantile v0.0.0-20220407130108-4246515d968d 15 | github.com/stretchr/testify v1.5.1 16 | github.com/uber-go/tally v3.3.15+incompatible 17 | github.com/uber/jaeger-client-go v2.22.1+incompatible 18 | go.uber.org/atomic v1.6.0 19 | go.uber.org/multierr v1.2.0 20 | golang.org/x/net v0.14.0 21 | golang.org/x/sys v0.11.0 22 | gopkg.in/yaml.v2 v2.4.0 23 | ) 24 | 25 | require ( 26 | github.com/davecgh/go-spew v1.1.1 // indirect 27 | github.com/kr/text v0.2.0 // indirect 28 | github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect 29 | github.com/pmezard/go-difflib v1.0.0 // indirect 30 | github.com/stretchr/objx v0.3.0 // indirect 31 | github.com/uber/jaeger-lib v2.4.1+incompatible // indirect 32 | golang.org/x/tools v0.1.12 // indirect 33 | gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect 34 | ) 35 | -------------------------------------------------------------------------------- /handlers_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package tchannel 22 | 23 | import ( 24 | "testing" 25 | 26 | "github.com/stretchr/testify/assert" 27 | "golang.org/x/net/context" 28 | ) 29 | 30 | type dummyHandler struct{} 31 | 32 | func (dummyHandler) Handle(ctx context.Context, call *InboundCall) {} 33 | 34 | func TestHandlers(t *testing.T) { 35 | const ( 36 | m1 = "m1" 37 | m2 = "m2" 38 | ) 39 | var ( 40 | hmap = &handlerMap{} 41 | 42 | h1 = &dummyHandler{} 43 | h2 = &dummyHandler{} 44 | 45 | m1b = []byte(m1) 46 | m2b = []byte(m2) 47 | ) 48 | 49 | assert.Nil(t, hmap.find(m1b)) 50 | assert.Nil(t, hmap.find(m2b)) 51 | 52 | hmap.Register(h1, m1) 53 | assert.Equal(t, h1, hmap.find(m1b)) 54 | assert.Nil(t, hmap.find(m2b)) 55 | 56 | hmap.Register(h2, m2) 57 | assert.Equal(t, h1, hmap.find(m1b)) 58 | assert.Equal(t, h2, hmap.find(m2b)) 59 | } 60 | -------------------------------------------------------------------------------- /http/buf.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package http 22 | 23 | import ( 24 | "net/http" 25 | 26 | "github.com/uber/tchannel-go/typed" 27 | ) 28 | 29 | func writeHeaders(wb *typed.WriteBuffer, form http.Header) { 30 | numHeadersDeferred := wb.DeferUint16() 31 | numHeaders := uint16(0) 32 | for k, values := range form { 33 | for _, v := range values { 34 | wb.WriteLen16String(k) 35 | wb.WriteLen16String(v) 36 | numHeaders++ 37 | } 38 | } 39 | numHeadersDeferred.Update(numHeaders) 40 | } 41 | 42 | func readHeaders(rb *typed.ReadBuffer, form http.Header) { 43 | numHeaders := rb.ReadUint16() 44 | for i := 0; i < int(numHeaders); i++ { 45 | k := rb.ReadLen16String() 46 | v := rb.ReadLen16String() 47 | form[k] = append(form[k], v) 48 | } 49 | } 50 | 51 | func readVarintString(rb *typed.ReadBuffer) string { 52 | length := rb.ReadUvarint() 53 | return rb.ReadString(int(length)) 54 | } 55 | 56 | func writeVarintString(wb *typed.WriteBuffer, s string) { 57 | wb.WriteUvarint(uint64(len(s))) 58 | wb.WriteString(s) 59 | } 60 | -------------------------------------------------------------------------------- /http/buf_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package http 22 | 23 | import ( 24 | "net/http" 25 | "testing" 26 | 27 | "github.com/stretchr/testify/assert" 28 | "github.com/uber/tchannel-go/testutils" 29 | "github.com/uber/tchannel-go/typed" 30 | ) 31 | 32 | func TestHeaders(t *testing.T) { 33 | tests := []http.Header{ 34 | {}, 35 | { 36 | "K1": []string{"K1V1", "K1V2", "K1V3"}, 37 | "K2": []string{"K2V2", "K2V2"}, 38 | }, 39 | } 40 | 41 | for _, tt := range tests { 42 | buf := make([]byte, 1000) 43 | wb := typed.NewWriteBuffer(buf) 44 | writeHeaders(wb, tt) 45 | 46 | newHeaders := make(http.Header) 47 | rb := typed.NewReadBuffer(buf) 48 | readHeaders(rb, newHeaders) 49 | assert.Equal(t, tt, newHeaders, "Headers mismatch") 50 | } 51 | } 52 | 53 | func TestVarintString(t *testing.T) { 54 | tests := []string{ 55 | "", 56 | "short string", 57 | testutils.RandString(1000), 58 | } 59 | 60 | for _, tt := range tests { 61 | buf := make([]byte, 2000) 62 | wb := typed.NewWriteBuffer(buf) 63 | writeVarintString(wb, tt) 64 | 65 | rb := typed.NewReadBuffer(buf) 66 | got := readVarintString(rb) 67 | assert.Equal(t, tt, got, "Varint string mismatch") 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /hyperbahn/configuration.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package hyperbahn 22 | 23 | // Configuration is the initial configuration 24 | type Configuration struct { 25 | // InitialNodes is the list of known Hyperbahn nodes to add initially. 26 | InitialNodes []string 27 | // InitialNodesFile is a JSON file that contains the list of known Hyperbahn nodes. 28 | // If this option is set, it overrides InitialNodes. 29 | InitialNodesFile string 30 | } 31 | -------------------------------------------------------------------------------- /hyperbahn/discover.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package hyperbahn 22 | 23 | import ( 24 | "time" 25 | 26 | "github.com/uber/tchannel-go/hyperbahn/gen-go/hyperbahn" 27 | "github.com/uber/tchannel-go/thrift" 28 | ) 29 | 30 | // Discover queries Hyperbahn for a list of peers that are currently 31 | // advertised with the specified service name. 32 | func (c *Client) Discover(serviceName string) ([]string, error) { 33 | ctx, cancel := thrift.NewContext(time.Second) 34 | defer cancel() 35 | 36 | result, err := c.hyperbahnClient.Discover(ctx, &hyperbahn.DiscoveryQuery{ServiceName: serviceName}) 37 | if err != nil { 38 | return nil, err 39 | } 40 | 41 | var hostPorts []string 42 | for _, peer := range result.GetPeers() { 43 | hostPorts = append(hostPorts, servicePeerToHostPort(peer)) 44 | } 45 | 46 | return hostPorts, nil 47 | } 48 | -------------------------------------------------------------------------------- /hyperbahn/event_string.go: -------------------------------------------------------------------------------- 1 | // generated by stringer -type=Event; DO NOT EDIT 2 | 3 | package hyperbahn 4 | 5 | import "fmt" 6 | 7 | const _Event_name = "UnknownEventRegistrationAttemptRegisteredRegistrationRefreshed" 8 | 9 | var _Event_index = [...]uint8{0, 12, 31, 41, 62} 10 | 11 | func (i Event) String() string { 12 | if i < 0 || i+1 >= Event(len(_Event_index)) { 13 | return fmt.Sprintf("Event(%d)", i) 14 | } 15 | return _Event_name[_Event_index[i]:_Event_index[i+1]] 16 | } 17 | -------------------------------------------------------------------------------- /hyperbahn/events.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package hyperbahn 22 | 23 | // Event describes different events that Client can trigger. 24 | type Event int 25 | 26 | const ( 27 | // UnknownEvent should never be used. 28 | UnknownEvent Event = iota 29 | // SendAdvertise is triggered when the Hyperbahn client tries to advertise. 30 | SendAdvertise 31 | // Advertised is triggered when the initial advertisement for a service is successful. 32 | Advertised 33 | // Readvertised is triggered on periodic advertisements. 34 | Readvertised 35 | ) 36 | 37 | //go:generate stringer -type=Event 38 | 39 | // Handler is the interface for handling Hyperbahn events and errors. 40 | type Handler interface { 41 | // On is called when events are triggered. 42 | On(event Event) 43 | // OnError is called when an error is detected. 44 | OnError(err error) 45 | } 46 | 47 | // nullHandler is the default Handler if nil is passed, so handlers can always be called. 48 | type nullHandler struct{} 49 | 50 | func (nullHandler) On(event Event) {} 51 | func (nullHandler) OnError(err error) {} 52 | -------------------------------------------------------------------------------- /hyperbahn/gen-go/hyperbahn/constants.go: -------------------------------------------------------------------------------- 1 | // Autogenerated by Thrift Compiler (1.0.0-dev) 2 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 3 | 4 | package hyperbahn 5 | 6 | import ( 7 | "bytes" 8 | "fmt" 9 | "github.com/uber/tchannel-go/thirdparty/github.com/apache/thrift/lib/go/thrift" 10 | ) 11 | 12 | // (needed to ensure safety because of naive import list construction.) 13 | var _ = thrift.ZERO 14 | var _ = fmt.Printf 15 | var _ = bytes.Equal 16 | 17 | func init() { 18 | } 19 | -------------------------------------------------------------------------------- /hyperbahn/hyperbahn.thrift: -------------------------------------------------------------------------------- 1 | exception NoPeersAvailable { 2 | 1: required string message 3 | 2: required string serviceName 4 | } 5 | 6 | exception InvalidServiceName { 7 | 1: required string message 8 | 2: required string serviceName 9 | } 10 | 11 | struct DiscoveryQuery { 12 | 1: required string serviceName 13 | } 14 | 15 | union IpAddress { 16 | 1: i32 ipv4 17 | } 18 | 19 | struct ServicePeer { 20 | 1: required IpAddress ip 21 | 2: required i32 port 22 | } 23 | 24 | struct DiscoveryResult { 25 | 1: required list peers 26 | } 27 | 28 | service Hyperbahn { 29 | DiscoveryResult discover( 30 | 1: required DiscoveryQuery query 31 | ) throws ( 32 | 1: NoPeersAvailable noPeersAvailable 33 | 2: InvalidServiceName invalidServiceName 34 | ) 35 | } -------------------------------------------------------------------------------- /hyperbahn/utils.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package hyperbahn 22 | 23 | import ( 24 | "net" 25 | "strconv" 26 | 27 | "github.com/uber/tchannel-go/hyperbahn/gen-go/hyperbahn" 28 | ) 29 | 30 | // intToIP4 converts an integer IP representation into a 4-byte net.IP struct 31 | func intToIP4(ip uint32) net.IP { 32 | return net.IP{ 33 | byte(ip >> 24 & 0xff), 34 | byte(ip >> 16 & 0xff), 35 | byte(ip >> 8 & 0xff), 36 | byte(ip & 0xff), 37 | } 38 | } 39 | 40 | // servicePeerToHostPort converts a Hyperbahn ServicePeer into a hostPort string. 41 | func servicePeerToHostPort(peer *hyperbahn.ServicePeer) string { 42 | host := intToIP4(uint32(*peer.IP.Ipv4)).String() 43 | port := strconv.Itoa(int(peer.Port)) 44 | return net.JoinHostPort(host, port) 45 | } 46 | -------------------------------------------------------------------------------- /hyperbahn/utils_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package hyperbahn 22 | 23 | import ( 24 | "testing" 25 | 26 | "github.com/stretchr/testify/assert" 27 | ) 28 | 29 | func TestIntToIP4(t *testing.T) { 30 | tests := []struct { 31 | ip uint32 32 | expected string 33 | }{ 34 | { 35 | ip: 0, 36 | expected: "0.0.0.0", 37 | }, 38 | { 39 | ip: 0x01010101, 40 | expected: "1.1.1.1", 41 | }, 42 | { 43 | ip: 0x01030507, 44 | expected: "1.3.5.7", 45 | }, 46 | { 47 | ip: 0xFFFFFFFF, 48 | expected: "255.255.255.255", 49 | }, 50 | } 51 | 52 | for _, tt := range tests { 53 | got := intToIP4(tt.ip).String() 54 | assert.Equal(t, tt.expected, got, "IP %v not converted correctly", tt.ip) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /internal/argreader/empty.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package argreader 22 | 23 | import ( 24 | "fmt" 25 | "io" 26 | "sync" 27 | ) 28 | 29 | var _bufPool = sync.Pool{ 30 | New: func() interface{} { 31 | b := make([]byte, 128) 32 | return &b 33 | }, 34 | } 35 | 36 | // EnsureEmpty ensures that the specified reader is empty. If the reader is 37 | // not empty, it returns an error with the specified stage in the message. 38 | func EnsureEmpty(r io.Reader, stage string) error { 39 | buf := _bufPool.Get().(*[]byte) 40 | defer _bufPool.Put(buf) 41 | 42 | n, err := r.Read(*buf) 43 | if n > 0 { 44 | return fmt.Errorf("found unexpected bytes after %s, found (upto 128 bytes): %x", stage, (*buf)[:n]) 45 | } 46 | if err == io.EOF { 47 | return nil 48 | } 49 | return err 50 | } 51 | -------------------------------------------------------------------------------- /internal/argreader/empty_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package argreader 22 | 23 | import ( 24 | "bytes" 25 | "testing" 26 | 27 | "github.com/uber/tchannel-go/testutils/testreader" 28 | 29 | "github.com/stretchr/testify/assert" 30 | "github.com/stretchr/testify/require" 31 | ) 32 | 33 | func TestEnsureEmptySuccess(t *testing.T) { 34 | reader := bytes.NewReader(nil) 35 | err := EnsureEmpty(reader, "success") 36 | require.NoError(t, err, "ensureEmpty should succeed with empty reader") 37 | } 38 | 39 | func TestEnsureEmptyHasBytes(t *testing.T) { 40 | reader := bytes.NewReader([]byte{1, 2, 3}) 41 | err := EnsureEmpty(reader, "T") 42 | require.Error(t, err, "ensureEmpty should fail when there's bytes") 43 | assert.Equal(t, err.Error(), "found unexpected bytes after T, found (upto 128 bytes): 010203") 44 | } 45 | 46 | func TestEnsureEmptyError(t *testing.T) { 47 | control, reader := testreader.ChunkReader() 48 | control <- nil 49 | close(control) 50 | 51 | err := EnsureEmpty(reader, "has bytes") 52 | require.Error(t, err, "ensureEmpty should fail when there's an error") 53 | assert.Equal(t, testreader.ErrUser, err, "Unexpected error") 54 | } 55 | -------------------------------------------------------------------------------- /json/context.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package json 22 | 23 | import ( 24 | "time" 25 | 26 | "github.com/uber/tchannel-go" 27 | 28 | "golang.org/x/net/context" 29 | ) 30 | 31 | // Context is a JSON Context which contains request and response headers. 32 | type Context tchannel.ContextWithHeaders 33 | 34 | // NewContext returns a Context that can be used to make JSON calls. 35 | func NewContext(timeout time.Duration) (Context, context.CancelFunc) { 36 | ctx, cancel := tchannel.NewContext(timeout) 37 | return tchannel.WrapWithHeaders(ctx, nil), cancel 38 | } 39 | 40 | // Wrap returns a JSON Context that wraps around a Context. 41 | func Wrap(ctx context.Context) Context { 42 | return tchannel.WrapWithHeaders(ctx, nil) 43 | } 44 | 45 | // WithHeaders returns a Context that can be used to make a call with request headers. 46 | func WithHeaders(ctx context.Context, headers map[string]string) Context { 47 | return tchannel.WrapWithHeaders(ctx, headers) 48 | } 49 | -------------------------------------------------------------------------------- /messagetype_string.go: -------------------------------------------------------------------------------- 1 | // Code generated by "stringer -type=messageType"; DO NOT EDIT. 2 | 3 | package tchannel 4 | 5 | import "strconv" 6 | 7 | func _() { 8 | // An "invalid array index" compiler error signifies that the constant values have changed. 9 | // Re-run the stringer command to generate them again. 10 | var x [1]struct{} 11 | _ = x[messageTypeInitReq-1] 12 | _ = x[messageTypeInitRes-2] 13 | _ = x[messageTypeCallReq-3] 14 | _ = x[messageTypeCallRes-4] 15 | _ = x[messageTypeCallReqContinue-19] 16 | _ = x[messageTypeCallResContinue-20] 17 | _ = x[messageTypeCancel-192] 18 | _ = x[messageTypePingReq-208] 19 | _ = x[messageTypePingRes-209] 20 | _ = x[messageTypeError-255] 21 | } 22 | 23 | const ( 24 | _messageType_name_0 = "messageTypeInitReqmessageTypeInitResmessageTypeCallReqmessageTypeCallRes" 25 | _messageType_name_1 = "messageTypeCallReqContinuemessageTypeCallResContinue" 26 | _messageType_name_2 = "messageTypeCancel" 27 | _messageType_name_3 = "messageTypePingReqmessageTypePingRes" 28 | _messageType_name_4 = "messageTypeError" 29 | ) 30 | 31 | var ( 32 | _messageType_index_0 = [...]uint8{0, 18, 36, 54, 72} 33 | _messageType_index_1 = [...]uint8{0, 26, 52} 34 | _messageType_index_3 = [...]uint8{0, 18, 36} 35 | ) 36 | 37 | func (i messageType) String() string { 38 | switch { 39 | case 1 <= i && i <= 4: 40 | i -= 1 41 | return _messageType_name_0[_messageType_index_0[i]:_messageType_index_0[i+1]] 42 | case 19 <= i && i <= 20: 43 | i -= 19 44 | return _messageType_name_1[_messageType_index_1[i]:_messageType_index_1[i+1]] 45 | case i == 192: 46 | return _messageType_name_2 47 | case 208 <= i && i <= 209: 48 | i -= 208 49 | return _messageType_name_3[_messageType_index_3[i]:_messageType_index_3[i+1]] 50 | case i == 255: 51 | return _messageType_name_4 52 | default: 53 | return "messageType(" + strconv.FormatInt(int64(i), 10) + ")" 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /peer_bench_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package tchannel_test 22 | 23 | import ( 24 | "testing" 25 | "time" 26 | 27 | . "github.com/uber/tchannel-go" 28 | 29 | "github.com/uber/tchannel-go/testutils" 30 | 31 | "github.com/stretchr/testify/require" 32 | ) 33 | 34 | func benchmarkGetConnection(b *testing.B, numIncoming, numOutgoing int) { 35 | ctx, cancel := NewContext(10 * time.Second) 36 | defer cancel() 37 | 38 | s1 := testutils.NewServer(b, nil) 39 | s2 := testutils.NewServer(b, nil) 40 | defer s1.Close() 41 | defer s2.Close() 42 | 43 | for i := 0; i < numOutgoing; i++ { 44 | _, err := s1.Connect(ctx, s2.PeerInfo().HostPort) 45 | require.NoError(b, err, "Connect from s1 -> s2 failed") 46 | } 47 | for i := 0; i < numIncoming; i++ { 48 | _, err := s2.Connect(ctx, s1.PeerInfo().HostPort) 49 | require.NoError(b, err, "Connect from s2 -> s1 failed") 50 | } 51 | 52 | peer := s1.Peers().GetOrAdd(s2.PeerInfo().HostPort) 53 | b.ResetTimer() 54 | for i := 0; i < b.N; i++ { 55 | peer.GetConnection(ctx) 56 | } 57 | } 58 | 59 | func BenchmarkGetConnection0In1Out(b *testing.B) { benchmarkGetConnection(b, 0, 1) } 60 | func BenchmarkGetConnection1In0Out(b *testing.B) { benchmarkGetConnection(b, 1, 0) } 61 | func BenchmarkGetConnection5In5Out(b *testing.B) { benchmarkGetConnection(b, 5, 5) } 62 | -------------------------------------------------------------------------------- /peer_heap_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package tchannel 22 | 23 | import ( 24 | "math" 25 | "math/rand" 26 | "testing" 27 | "time" 28 | 29 | "github.com/stretchr/testify/assert" 30 | ) 31 | 32 | func TestPeerHeap(t *testing.T) { 33 | const numPeers = 10 34 | r := rand.New(rand.NewSource(time.Now().UnixNano())) 35 | 36 | peerHeap := newPeerHeap() 37 | 38 | peerScores := make([]*peerScore, numPeers) 39 | minScore := uint64(math.MaxInt64) 40 | for i := 0; i < numPeers; i++ { 41 | ps := newPeerScore(&Peer{}, uint64(r.Intn(numPeers*5))) 42 | peerScores[i] = ps 43 | if ps.score < minScore { 44 | minScore = ps.score 45 | } 46 | } 47 | 48 | for i := 0; i < numPeers; i++ { 49 | peerHeap.pushPeer(peerScores[i]) 50 | } 51 | 52 | assert.Equal(t, numPeers, peerHeap.Len(), "Incorrect peer heap numPeers") 53 | assert.Equal(t, minScore, peerHeap.peek().score, "peerHeap top peer is not minimum") 54 | 55 | lastScore := peerHeap.popPeer().score 56 | for i := 1; i < numPeers; i++ { 57 | assert.Equal(t, numPeers-i, peerHeap.Len(), "Incorrect peer heap numPeers") 58 | score := peerHeap.popPeer().score 59 | assert.True(t, score >= lastScore, "The order of the heap is invalid") 60 | lastScore = score 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /peer_internal_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package tchannel 22 | 23 | import ( 24 | "testing" 25 | 26 | "github.com/stretchr/testify/assert" 27 | ) 28 | 29 | func TestIsEphemeralHostPort(t *testing.T) { 30 | tests := []struct { 31 | hostPort string 32 | want bool 33 | }{ 34 | {"", true}, 35 | {ephemeralHostPort, true}, 36 | {"127.0.0.1:0", true}, 37 | {"10.1.1.1:0", true}, 38 | {"127.0.0.1:1", false}, 39 | {"10.1.1.1:1", false}, 40 | } 41 | 42 | for _, tt := range tests { 43 | got := isEphemeralHostPort(tt.hostPort) 44 | assert.Equal(t, tt.want, got, "Unexpected result for %q", tt.hostPort) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /peers/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | /* 22 | Package peers provides helpers for managing TChannel peers. 23 | */ 24 | package peers 25 | -------------------------------------------------------------------------------- /pprof/pprof.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package pprof 22 | 23 | import ( 24 | "net/http" 25 | _ "net/http/pprof" // So pprof endpoints are registered on DefaultServeMux. 26 | 27 | "github.com/uber/tchannel-go" 28 | thttp "github.com/uber/tchannel-go/http" 29 | 30 | "golang.org/x/net/context" 31 | ) 32 | 33 | func serveHTTP(req *http.Request, response *tchannel.InboundCallResponse) { 34 | rw, finish := thttp.ResponseWriter(response) 35 | http.DefaultServeMux.ServeHTTP(rw, req) 36 | finish() 37 | } 38 | 39 | // Register registers pprof endpoints on the given registrar under _pprof. 40 | // The _pprof endpoint uses as-http and is a tunnel to the default serve mux. 41 | func Register(registrar tchannel.Registrar) { 42 | handler := func(ctx context.Context, call *tchannel.InboundCall) { 43 | req, err := thttp.ReadRequest(call) 44 | if err != nil { 45 | registrar.Logger().WithFields( 46 | tchannel.LogField{Key: "err", Value: err.Error()}, 47 | ).Warn("Failed to read HTTP request.") 48 | return 49 | } 50 | 51 | serveHTTP(req, call.Response()) 52 | } 53 | registrar.Register(tchannel.HandlerFunc(handler), "_pprof") 54 | } 55 | -------------------------------------------------------------------------------- /pprof/pprof_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package pprof 22 | 23 | import ( 24 | "io/ioutil" 25 | "net/http" 26 | "testing" 27 | "time" 28 | 29 | "github.com/uber/tchannel-go" 30 | thttp "github.com/uber/tchannel-go/http" 31 | "github.com/uber/tchannel-go/testutils" 32 | 33 | "github.com/stretchr/testify/assert" 34 | "github.com/stretchr/testify/require" 35 | ) 36 | 37 | func TestPProfEndpoint(t *testing.T) { 38 | ch := testutils.NewServer(t, nil) 39 | Register(ch) 40 | 41 | ctx, cancel := tchannel.NewContext(time.Second) 42 | defer cancel() 43 | 44 | req, err := http.NewRequest("GET", "/debug/pprof/block?debug=1", nil) 45 | require.NoError(t, err, "NewRequest failed") 46 | 47 | call, err := ch.BeginCall(ctx, ch.PeerInfo().HostPort, ch.ServiceName(), "_pprof", nil) 48 | require.NoError(t, err, "BeginCall failed") 49 | require.NoError(t, err, thttp.WriteRequest(call, req), "thttp.WriteRequest failed") 50 | 51 | response, err := thttp.ReadResponse(call.Response()) 52 | require.NoError(t, err, "ReadResponse failed") 53 | 54 | assert.Equal(t, http.StatusOK, response.StatusCode) 55 | body, err := ioutil.ReadAll(response.Body) 56 | if assert.NoError(t, err, "Read body failed") { 57 | assert.Contains(t, string(body), "contention", "Response does not contain expected string") 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /relay/relaytest/func_host.go: -------------------------------------------------------------------------------- 1 | package relaytest 2 | 3 | import ( 4 | "github.com/uber/tchannel-go" 5 | "github.com/uber/tchannel-go/relay" 6 | ) 7 | 8 | // Ensure that the hostFunc implements tchannel.RelayHost and hostFuncPeer implements 9 | // tchannel.RelayCall 10 | var _ tchannel.RelayHost = (*hostFunc)(nil) 11 | var _ tchannel.RelayCall = (*hostFuncPeer)(nil) 12 | 13 | type hostFunc struct { 14 | ch *tchannel.Channel 15 | stats *MockStats 16 | fn func(relay.CallFrame, *relay.Conn) (string, error) 17 | } 18 | 19 | type hostFuncPeer struct { 20 | *MockCallStats 21 | 22 | peer *tchannel.Peer 23 | respFrame relay.RespFrame 24 | } 25 | 26 | // HostFunc wraps a given function to implement tchannel.RelayHost. 27 | func HostFunc(fn func(relay.CallFrame, *relay.Conn) (string, error)) tchannel.RelayHost { 28 | return &hostFunc{fn: fn} 29 | } 30 | 31 | func (hf *hostFunc) SetChannel(ch *tchannel.Channel) { 32 | hf.ch = ch 33 | hf.stats = NewMockStats() 34 | } 35 | 36 | func (hf *hostFunc) Start(cf relay.CallFrame, conn *relay.Conn) (tchannel.RelayCall, error) { 37 | var peer *tchannel.Peer 38 | 39 | peerHP, err := hf.fn(cf, conn) 40 | if peerHP != "" { 41 | peer = hf.ch.GetSubChannel(string(cf.Service())).Peers().GetOrAdd(peerHP) 42 | } 43 | 44 | // We still track stats if we failed to get a peer, so return the peer. 45 | return &hostFuncPeer{MockCallStats: hf.stats.Begin(cf), peer: peer}, err 46 | } 47 | 48 | func (hf *hostFunc) Stats() *MockStats { 49 | return hf.stats 50 | } 51 | 52 | func (p *hostFuncPeer) Destination() (*tchannel.Peer, bool) { 53 | return p.peer, p.peer != nil 54 | } 55 | 56 | func (p *hostFuncPeer) CallResponse(frame relay.RespFrame) { 57 | p.respFrame = frame 58 | } 59 | -------------------------------------------------------------------------------- /relay_messages_benchmark_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package tchannel 22 | 23 | import ( 24 | "fmt" 25 | "io/ioutil" 26 | "testing" 27 | ) 28 | 29 | func BenchmarkCallReqFrame(b *testing.B) { 30 | cr := reqHasAll.req(b) 31 | f := cr.Frame 32 | 33 | var service, caller, method []byte 34 | 35 | b.ResetTimer() 36 | for i := 0; i < b.N; i++ { 37 | cr, err := newLazyCallReq(f) 38 | if err != nil { 39 | b.Fatal("Unexpected error") 40 | } 41 | 42 | // Multiple calls due to peer selection, stats, etc. 43 | for i := 0; i < 3; i++ { 44 | service = cr.Service() 45 | caller = cr.Caller() 46 | method = cr.Method() 47 | } 48 | } 49 | b.StopTimer() 50 | 51 | fmt.Fprint(ioutil.Discard, service, caller, method) 52 | } 53 | -------------------------------------------------------------------------------- /reqresreaderstate_string.go: -------------------------------------------------------------------------------- 1 | // generated by stringer -type=reqResReaderState; DO NOT EDIT 2 | 3 | package tchannel 4 | 5 | import "fmt" 6 | 7 | const _reqResReaderState_name = "reqResReaderPreArg1reqResReaderPreArg2reqResReaderPreArg3reqResReaderComplete" 8 | 9 | var _reqResReaderState_index = [...]uint8{0, 19, 38, 57, 77} 10 | 11 | func (i reqResReaderState) String() string { 12 | if i < 0 || i+1 >= reqResReaderState(len(_reqResReaderState_index)) { 13 | return fmt.Sprintf("reqResReaderState(%d)", i) 14 | } 15 | return _reqResReaderState_name[_reqResReaderState_index[i]:_reqResReaderState_index[i+1]] 16 | } 17 | -------------------------------------------------------------------------------- /reqreswriterstate_string.go: -------------------------------------------------------------------------------- 1 | // generated by stringer -type=reqResWriterState; DO NOT EDIT 2 | 3 | package tchannel 4 | 5 | import "fmt" 6 | 7 | const _reqResWriterState_name = "reqResWriterPreArg1reqResWriterPreArg2reqResWriterPreArg3reqResWriterComplete" 8 | 9 | var _reqResWriterState_index = [...]uint8{0, 19, 38, 57, 77} 10 | 11 | func (i reqResWriterState) String() string { 12 | if i < 0 || i+1 >= reqResWriterState(len(_reqResWriterState_index)) { 13 | return fmt.Sprintf("reqResWriterState(%d)", i) 14 | } 15 | return _reqResWriterState_name[_reqResWriterState_index[i]:_reqResWriterState_index[i+1]] 16 | } 17 | -------------------------------------------------------------------------------- /retryon_string.go: -------------------------------------------------------------------------------- 1 | // generated by stringer -type=RetryOn; DO NOT EDIT 2 | 3 | package tchannel 4 | 5 | import "fmt" 6 | 7 | const _RetryOn_name = "RetryDefaultRetryConnectionErrorRetryNeverRetryNonIdempotentRetryUnexpectedRetryIdempotent" 8 | 9 | var _RetryOn_index = [...]uint8{0, 12, 32, 42, 60, 75, 90} 10 | 11 | func (i RetryOn) String() string { 12 | if i < 0 || i+1 >= RetryOn(len(_RetryOn_index)) { 13 | return fmt.Sprintf("RetryOn(%d)", i) 14 | } 15 | return _RetryOn_name[_RetryOn_index[i]:_RetryOn_index[i+1]] 16 | } 17 | -------------------------------------------------------------------------------- /scripts/install-thrift.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euo pipefail 4 | 5 | if [ -z "${1}" ]; then 6 | echo "usage: ${0} installDirPath" >&2 7 | exit 1 8 | fi 9 | 10 | BIN_FILE="thrift-1" 11 | TAR_FILE="${BIN_FILE}-$(uname -s | tr '[:upper:]' '[:lower:]')-$(uname -m).tar.gz" 12 | TAR_LOCATION="https://github.com/uber/tchannel-go/releases/download/thrift-v1.0.0-dev/${TAR_FILE}" 13 | 14 | mkdir -p "${1}" 15 | cd "${1}" 16 | wget "${TAR_LOCATION}" 17 | tar xzf "${TAR_FILE}" 18 | rm -f "${TAR_FILE}" 19 | mv "${BIN_FILE}" "thrift" 20 | -------------------------------------------------------------------------------- /sockio_bsd.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | //go:build aix || darwin || dragonfly || freebsd || netbsd || openbsd || solaris 22 | // +build aix darwin dragonfly freebsd netbsd openbsd solaris 23 | 24 | package tchannel 25 | 26 | import "golang.org/x/sys/unix" 27 | 28 | func getSendQueueLen(fd uintptr) (int, error) { 29 | return unix.IoctlGetInt(int(fd), unix.TIOCOUTQ) 30 | } 31 | -------------------------------------------------------------------------------- /sockio_darwin.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | //go:build darwin 22 | // +build darwin 23 | 24 | package tchannel 25 | 26 | import "golang.org/x/sys/unix" 27 | 28 | func getSendQueueLen(fd uintptr) (int, error) { 29 | // https://www.unix.com/man-page/osx/2/getsockopt/ 30 | return unix.GetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_NWRITE) 31 | } 32 | -------------------------------------------------------------------------------- /sockio_linux.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | //go:build linux 22 | // +build linux 23 | 24 | package tchannel 25 | 26 | import "golang.org/x/sys/unix" 27 | 28 | func getSendQueueLen(fd uintptr) (int, error) { 29 | // https://linux.die.net/man/7/tcp 30 | return unix.IoctlGetInt(int(fd), unix.SIOCOUTQ) 31 | } 32 | -------------------------------------------------------------------------------- /sockio_non_unix.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | // Opposite of sockio_unix.go 22 | //go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris 23 | // +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris 24 | 25 | package tchannel 26 | 27 | func (c *Connection) sendBufSize() (sendBufUsage int, sendBufSize int, _ error) { 28 | return -1, -1, errNoSyscallConn 29 | } 30 | -------------------------------------------------------------------------------- /sockio_unix.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | // Match the golang/sys unix file, https://github.com/golang/sys/blob/master/unix/syscall_unix.go#L5 22 | //go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris 23 | // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris 24 | 25 | package tchannel 26 | 27 | import ( 28 | "go.uber.org/multierr" 29 | "golang.org/x/sys/unix" 30 | ) 31 | 32 | func (c *Connection) sendBufSize() (sendBufUsage int, sendBufSize int, _ error) { 33 | sendBufSize = -1 34 | sendBufUsage = -1 35 | 36 | if c.sysConn == nil { 37 | return sendBufUsage, sendBufSize, errNoSyscallConn 38 | } 39 | 40 | var sendBufLenErr, sendBufLimErr error 41 | errs := c.sysConn.Control(func(fd uintptr) { 42 | sendBufUsage, sendBufLenErr = getSendQueueLen(fd) 43 | sendBufSize, sendBufLimErr = unix.GetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_SNDBUF) 44 | }) 45 | 46 | errs = multierr.Append(errs, sendBufLimErr) 47 | errs = multierr.Append(errs, sendBufLenErr) 48 | return sendBufUsage, sendBufSize, errs 49 | } 50 | -------------------------------------------------------------------------------- /stress_flag_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package tchannel_test 22 | 23 | import ( 24 | "flag" 25 | "testing" 26 | ) 27 | 28 | // This file contains functions for tests to access internal tchannel state. 29 | // Since it has a _test.go suffix, it is only compiled with tests in this package. 30 | 31 | var flagStressTest = flag.Bool("stressTest", false, "Run stress tests (very slow)") 32 | 33 | // CheckStress will skip the test if stress testing is not enabled. 34 | func CheckStress(t *testing.T) { 35 | if !*flagStressTest { 36 | t.Skip("Skipping long-running test as stressTest is not set") 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /systemerrcode_string.go: -------------------------------------------------------------------------------- 1 | // generated by stringer -type=SystemErrCode; DO NOT EDIT 2 | 3 | package tchannel 4 | 5 | import "fmt" 6 | 7 | const ( 8 | _SystemErrCode_name_0 = "ErrCodeInvalidErrCodeTimeoutErrCodeCancelledErrCodeBusyErrCodeDeclinedErrCodeUnexpectedErrCodeBadRequestErrCodeNetwork" 9 | _SystemErrCode_name_1 = "ErrCodeProtocol" 10 | ) 11 | 12 | var ( 13 | _SystemErrCode_index_0 = [...]uint8{0, 14, 28, 44, 55, 70, 87, 104, 118} 14 | _SystemErrCode_index_1 = [...]uint8{0, 15} 15 | ) 16 | 17 | func (i SystemErrCode) String() string { 18 | switch { 19 | case 0 <= i && i <= 7: 20 | return _SystemErrCode_name_0[_SystemErrCode_index_0[i]:_SystemErrCode_index_0[i+1]] 21 | case i == 255: 22 | return _SystemErrCode_name_1 23 | default: 24 | return fmt.Sprintf("SystemErrCode(%d)", i) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tchannel_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package tchannel_test 22 | 23 | import ( 24 | "flag" 25 | "fmt" 26 | "os" 27 | "testing" 28 | 29 | . "github.com/uber/tchannel-go" 30 | 31 | "github.com/uber/tchannel-go/testutils/goroutines" 32 | ) 33 | 34 | func checkAllChannels() error { 35 | ch, err := NewChannel("test-end", nil) 36 | if err != nil { 37 | return err 38 | } 39 | 40 | var foundChannels bool 41 | allChannels := ch.IntrospectOthers(&IntrospectionOptions{}) 42 | for _, cs := range allChannels { 43 | if len(cs) != 0 { 44 | foundChannels = true 45 | } 46 | } 47 | 48 | if !foundChannels { 49 | return nil 50 | } 51 | 52 | return fmt.Errorf("unclosed channels:\n%+v", allChannels) 53 | } 54 | 55 | func TestMain(m *testing.M) { 56 | flag.Parse() 57 | exitCode := m.Run() 58 | 59 | if exitCode == 0 { 60 | // Only do extra checks if the tests were successful. 61 | if err := goroutines.IdentifyLeaks(nil); err != nil { 62 | fmt.Fprintf(os.Stderr, "Found goroutine leaks on successful test run: %v", err) 63 | exitCode = 1 64 | } 65 | 66 | if err := checkAllChannels(); err != nil { 67 | fmt.Fprintf(os.Stderr, "Found unclosed channels on successful test run: %v", err) 68 | exitCode = 1 69 | } 70 | } 71 | 72 | os.Exit(exitCode) 73 | } 74 | -------------------------------------------------------------------------------- /testutils/conn.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package testutils 22 | 23 | import ( 24 | "net" 25 | "testing" 26 | ) 27 | 28 | // GetClosedHostPort will return a host:port that will refuse connections. 29 | func GetClosedHostPort(t testing.TB) string { 30 | listener, err := net.Listen("tcp", "127.0.0.1:0") 31 | if err != nil { 32 | t.Fatalf("net.Listen failed: %v", err) 33 | return "" 34 | } 35 | 36 | if err := listener.Close(); err != nil { 37 | t.Fatalf("listener.Close failed") 38 | return "" 39 | } 40 | 41 | return listener.Addr().String() 42 | } 43 | 44 | // GetAcceptCloseHostPort returns a host:port that will accept a connection then 45 | // immediately close it. The returned function can be used to stop the listener. 46 | func GetAcceptCloseHostPort(t testing.TB) (string, func()) { 47 | listener, err := net.Listen("tcp", "127.0.0.1:0") 48 | if err != nil { 49 | t.Fatalf("net.Listen failed: %v", err) 50 | return "", nil 51 | } 52 | 53 | go func() { 54 | for { 55 | conn, err := listener.Accept() 56 | if err != nil { 57 | return 58 | } 59 | 60 | conn.Close() 61 | } 62 | }() 63 | 64 | return listener.Addr().String(), func() { 65 | if err := listener.Close(); err != nil { 66 | t.Fatalf("listener.Close failed") 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /testutils/goroutines/verify_opts.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package goroutines 22 | 23 | import "bytes" 24 | 25 | // VerifyOpts contains 26 | type VerifyOpts struct { 27 | // Excludes is a list of strings that will exclude a stack from being considered a leak. 28 | Excludes []string 29 | } 30 | 31 | // ShouldSkip returns whether the given stack should be skipped when doing verification. 32 | func (opts *VerifyOpts) ShouldSkip(s Stack) bool { 33 | if opts == nil || len(opts.Excludes) == 0 { 34 | return false 35 | } 36 | 37 | for _, exclude := range opts.Excludes { 38 | if bytes.Contains(s.Full(), []byte(exclude)) { 39 | return true 40 | } 41 | } 42 | 43 | return false 44 | } 45 | -------------------------------------------------------------------------------- /testutils/lists.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package testutils 22 | 23 | import "time" 24 | 25 | // StrArray will return an array with the given strings. 26 | func StrArray(ss ...string) []string { 27 | return ss 28 | } 29 | 30 | // StrMap returns a map where the keys are the given strings. 31 | func StrMap(ss ...string) map[string]struct{} { 32 | m := make(map[string]struct{}, len(ss)) 33 | for _, v := range ss { 34 | m[v] = struct{}{} 35 | } 36 | return m 37 | } 38 | 39 | // DurationArray returns an array with the given durations. 40 | func DurationArray(dd ...time.Duration) []time.Duration { 41 | return dd 42 | } 43 | -------------------------------------------------------------------------------- /testutils/now.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package testutils 22 | 23 | import ( 24 | "sync" 25 | "time" 26 | ) 27 | 28 | // StubClock is a fake wall-clock, exposing a Now() method that returns a 29 | // test-controlled time. 30 | type StubClock struct { 31 | mu sync.Mutex 32 | cur time.Time 33 | } 34 | 35 | // NewStubClock returns a fake wall-clock object 36 | func NewStubClock(initial time.Time) *StubClock { 37 | return &StubClock{ 38 | cur: initial, 39 | } 40 | } 41 | 42 | // Now returns the current time stored in StubClock 43 | func (c *StubClock) Now() time.Time { 44 | c.mu.Lock() 45 | defer c.mu.Unlock() 46 | 47 | return c.cur 48 | } 49 | 50 | // Elapse increments the time returned by Now() 51 | func (c *StubClock) Elapse(addAmt time.Duration) { 52 | c.mu.Lock() 53 | defer c.mu.Unlock() 54 | 55 | c.cur = c.cur.Add(addAmt) 56 | } 57 | -------------------------------------------------------------------------------- /testutils/random_bench_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package testutils 22 | 23 | import ( 24 | "bytes" 25 | "io" 26 | "io/ioutil" 27 | "testing" 28 | ) 29 | 30 | func benchmarkRandom(b *testing.B, numBytes int) { 31 | var bs []byte 32 | for i := 0; i < b.N; i++ { 33 | randCache = nil 34 | bs = RandBytes(numBytes) 35 | } 36 | io.Copy(ioutil.Discard, bytes.NewReader(bs)) 37 | } 38 | 39 | func BenchmarkRandom256(b *testing.B) { 40 | benchmarkRandom(b, 256) 41 | } 42 | 43 | func BenchmarkRandom1024(b *testing.B) { 44 | benchmarkRandom(b, 1024) 45 | } 46 | 47 | func BenchmarkRandom4096(b *testing.B) { 48 | benchmarkRandom(b, 4096) 49 | } 50 | 51 | func BenchmarkRandom16384(b *testing.B) { 52 | benchmarkRandom(b, 16384) 53 | } 54 | 55 | func BenchmarkRandom32768(b *testing.B) { 56 | benchmarkRandom(b, 32768) 57 | } 58 | -------------------------------------------------------------------------------- /testutils/sleep.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package testutils 22 | 23 | import "time" 24 | 25 | // SleepStub stubs a function variable that points to time.Sleep. It returns 26 | // two channels to control the sleep stub, and a function to close the channels. 27 | // Once the stub is closed, any further sleeps will cause panics. 28 | // The two channels returned are: 29 | // <-chan time.Duration which will contain arguments that the stub was called with. 30 | // chan<- struct{} that should be written to when you want the Sleep to return. 31 | func SleepStub(funcVar *func(time.Duration)) ( 32 | argCh <-chan time.Duration, unblockCh chan<- struct{}, closeFn func()) { 33 | 34 | args := make(chan time.Duration) 35 | block := make(chan struct{}) 36 | *funcVar = func(t time.Duration) { 37 | args <- t 38 | <-block 39 | } 40 | closeSleepChans := func() { 41 | close(args) 42 | close(block) 43 | } 44 | return args, block, closeSleepChans 45 | } 46 | 47 | // ResetSleepStub resets a Sleep stub. 48 | func ResetSleepStub(funcVar *func(time.Duration)) { 49 | *funcVar = time.Sleep 50 | } 51 | -------------------------------------------------------------------------------- /testutils/testreader/chunk.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package testreader 22 | 23 | import ( 24 | "errors" 25 | "io" 26 | ) 27 | 28 | // ErrUser is returned by ChunkReader when the user requests an error. 29 | var ErrUser = errors.New("error set by user") 30 | 31 | // ChunkReader returns a reader that returns chunks written to the control channel. 32 | // The caller should write byte chunks to return to the channel, or write nil if they 33 | // want the Reader to return an error. The control channel should be closed to signal EOF. 34 | func ChunkReader() (chan<- []byte, io.Reader) { 35 | reader := &errorReader{ 36 | c: make(chan []byte, 100), 37 | } 38 | return reader.c, reader 39 | } 40 | 41 | type errorReader struct { 42 | c chan []byte 43 | remaining []byte 44 | } 45 | 46 | func (r *errorReader) Read(bs []byte) (int, error) { 47 | for len(r.remaining) == 0 { 48 | var ok bool 49 | r.remaining, ok = <-r.c 50 | if !ok { 51 | return 0, io.EOF 52 | } 53 | if r.remaining == nil { 54 | return 0, ErrUser 55 | } 56 | if len(r.remaining) == 0 { 57 | return 0, nil 58 | } 59 | } 60 | 61 | n := copy(bs, r.remaining) 62 | r.remaining = r.remaining[n:] 63 | return n, nil 64 | } 65 | -------------------------------------------------------------------------------- /testutils/testreader/loop.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package testreader 22 | 23 | import "io" 24 | 25 | type loopReader struct { 26 | bs []byte 27 | pos int 28 | } 29 | 30 | func (r loopReader) Read(p []byte) (int, error) { 31 | for i := range p { 32 | p[i] = r.bs[r.pos] 33 | if r.pos++; r.pos == len(r.bs) { 34 | r.pos = 0 35 | } 36 | } 37 | return len(p), nil 38 | } 39 | 40 | // Looper returns a reader that will return the bytes in bs as if it was a circular buffer. 41 | func Looper(bs []byte) io.Reader { 42 | return &loopReader{bs, 0} 43 | } 44 | -------------------------------------------------------------------------------- /testutils/testreader/loop_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package testreader 22 | 23 | import ( 24 | "testing" 25 | 26 | "github.com/stretchr/testify/assert" 27 | ) 28 | 29 | func TestLooper(t *testing.T) { 30 | tests := []struct { 31 | bs []byte 32 | expected []byte 33 | }{ 34 | {[]byte{0x1}, []byte{0x1, 0x1, 0x1}}, 35 | {[]byte{0x1, 0x2}, []byte{0x1, 0x2, 0x1}}, 36 | {[]byte{0x1, 0x2}, []byte{0x1, 0x2, 0x1, 0x2, 0x1, 0x2}}, 37 | } 38 | 39 | for _, tt := range tests { 40 | r := Looper(tt.bs) 41 | got := make([]byte, len(tt.expected)) 42 | n, err := r.Read(got) 43 | assert.NoError(t, err, "Read failed") 44 | assert.Equal(t, len(got), n) 45 | assert.Equal(t, tt.expected, got, "Got unexpected bytes") 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /testutils/testwriter/limited.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package testwriter 22 | 23 | import ( 24 | "errors" 25 | "io" 26 | ) 27 | 28 | // ErrOutOfSpace is returned by Limited reader when it is out of bytes. 29 | var ErrOutOfSpace = errors.New("out of space") 30 | 31 | type writerFunc func([]byte) (int, error) 32 | 33 | func (f writerFunc) Write(p []byte) (n int, err error) { 34 | return f(p) 35 | } 36 | 37 | // Limited returns an io.Writer that will only accept n bytes. 38 | // All further calls will cause an error. 39 | func Limited(n int) io.Writer { 40 | return writerFunc(func(p []byte) (int, error) { 41 | if n < len(p) { 42 | retN := n 43 | n = 0 44 | return retN, ErrOutOfSpace 45 | } 46 | 47 | n -= len(p) 48 | return len(p), nil 49 | }) 50 | } 51 | -------------------------------------------------------------------------------- /testutils/thriftarg2test/arg2_kv.go: -------------------------------------------------------------------------------- 1 | package thriftarg2test 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/require" 8 | "github.com/uber/tchannel-go/typed" 9 | ) 10 | 11 | // BuildKVBuffer builds an thrift Arg2 KV buffer. 12 | func BuildKVBuffer(kv map[string]string) []byte { 13 | // Scan once to know size of buffer 14 | var bufSize int 15 | for k, v := range kv { 16 | // k~2 v~2 17 | bufSize += 2 + len(k) + 2 + len(v) 18 | } 19 | bufSize += 2 // nh:2 20 | buf := make([]byte, bufSize) 21 | wb := typed.NewWriteBuffer(buf) 22 | wb.WriteUint16(uint16(len(kv))) 23 | for k, v := range kv { 24 | wb.WriteLen16String(k) 25 | wb.WriteLen16String(v) 26 | } 27 | return buf[:wb.BytesWritten()] 28 | } 29 | 30 | // ReadKVBuffer converts an arg2 buffer to a string map 31 | func ReadKVBuffer(b []byte) (map[string]string, error) { 32 | rbuf := typed.NewReadBuffer(b) 33 | nh := rbuf.ReadUint16() 34 | retMap := make(map[string]string, nh) 35 | for i := uint16(0); i < nh; i++ { 36 | key := rbuf.ReadLen16String() 37 | val := rbuf.ReadLen16String() 38 | retMap[key] = val 39 | } 40 | if rbuf.BytesRemaining() > 0 { 41 | return nil, fmt.Errorf("kv buffer wasn't fully consumed (%d bytes remaining)", rbuf.BytesRemaining()) 42 | } 43 | return retMap, nil 44 | } 45 | 46 | // MustReadKVBuffer calls require.NoError on the error returned by ReadKVBuffer 47 | func MustReadKVBuffer(tb testing.TB, b []byte) map[string]string { 48 | m, err := ReadKVBuffer(b) 49 | require.NoError(tb, err) 50 | return m 51 | } 52 | -------------------------------------------------------------------------------- /testutils/thriftarg2test/arg2_kv_test.go: -------------------------------------------------------------------------------- 1 | package thriftarg2test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | "github.com/uber/tchannel-go/typed" 8 | ) 9 | 10 | func TestBuildKVBuffer(t *testing.T) { 11 | kv := map[string]string{ 12 | "key": "valval", 13 | "key2": "val", 14 | } 15 | buf := BuildKVBuffer(kv) 16 | rb := typed.NewReadBuffer(buf) 17 | assert.EqualValues(t, len(kv), rb.ReadUint16()) 18 | 19 | gotKV := make(map[string]string) 20 | for i := 0; i < len(kv); i++ { 21 | k := rb.ReadLen16String() 22 | v := rb.ReadLen16String() 23 | gotKV[k] = v 24 | } 25 | assert.Equal(t, kv, gotKV) 26 | } 27 | 28 | func TestReadKVBuffer(t *testing.T) { 29 | kvMap := map[string]string{ 30 | "key": "valval", 31 | "key2": "val", 32 | } 33 | 34 | var buffer [128]byte 35 | wbuf := typed.NewWriteBuffer(buffer[:]) 36 | wbuf.WriteUint16(uint16(len(kvMap))) // nh 37 | 38 | // the order doesn't matter here since we're comparing maps 39 | for k, v := range kvMap { 40 | wbuf.WriteLen16String(k) 41 | wbuf.WriteLen16String(v) 42 | } 43 | assert.Equal(t, kvMap, MustReadKVBuffer(t, buffer[:wbuf.BytesWritten()])) 44 | } 45 | -------------------------------------------------------------------------------- /testutils/ticker.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package testutils 22 | 23 | import "time" 24 | 25 | // FakeTicker is a ticker for unit tests that can be controlled 26 | // deterministically. 27 | type FakeTicker struct { 28 | c chan time.Time 29 | } 30 | 31 | // NewFakeTicker returns a new instance of FakeTicker 32 | func NewFakeTicker() *FakeTicker { 33 | return &FakeTicker{ 34 | c: make(chan time.Time, 1), 35 | } 36 | } 37 | 38 | // Tick sends an immediate tick call to the receiver 39 | func (ft *FakeTicker) Tick() { 40 | ft.c <- time.Now() 41 | } 42 | 43 | // TryTick attempts to send a tick, if the channel isn't blocked. 44 | func (ft *FakeTicker) TryTick() bool { 45 | select { 46 | case ft.c <- time.Time{}: 47 | return true 48 | default: 49 | return false 50 | } 51 | } 52 | 53 | // New can be used in tests as a factory method for tickers, by passing it to 54 | // ChannelOptions.TimeTicker 55 | func (ft *FakeTicker) New(d time.Duration) *time.Ticker { 56 | t := time.NewTicker(time.Hour) 57 | t.C = ft.c 58 | return t 59 | } 60 | -------------------------------------------------------------------------------- /testutils/ticker_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package testutils 22 | 23 | import ( 24 | "testing" 25 | "time" 26 | 27 | "github.com/stretchr/testify/assert" 28 | ) 29 | 30 | func TestFakeTicker(t *testing.T) { 31 | ft := NewFakeTicker() 32 | 33 | ticker := ft.New(time.Second) 34 | select { 35 | case <-ticker.C: 36 | t.Fatalf("Fake ticker ticked by itself") 37 | default: 38 | } 39 | 40 | for i := 0; i < 10; i++ { 41 | if i%2 == 0 { 42 | assert.True(t, ft.TryTick(), "TryTick should succeed with no other pending ticks") 43 | assert.False(t, ft.TryTick(), "TryTick should fail with pending ticks") 44 | } else { 45 | ft.Tick() 46 | } 47 | 48 | select { 49 | case <-ticker.C: 50 | default: 51 | t.Fatalf("Fake ticker tick did not unblock ticker") 52 | } 53 | } 54 | 55 | ticker.Stop() 56 | select { 57 | case <-ticker.C: 58 | t.Fatalf("Stopped ticker ticked") 59 | default: 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /testutils/wait.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package testutils 22 | 23 | import ( 24 | "sync" 25 | "time" 26 | ) 27 | 28 | // WaitFor will retry f till it returns true for a maximum of timeout. 29 | // It returns true if f returned true, false if timeout was hit. 30 | func WaitFor(timeout time.Duration, f func() bool) bool { 31 | timeoutEnd := time.Now().Add(Timeout(timeout)) 32 | 33 | const maxSleep = time.Millisecond * 50 34 | sleepFor := time.Millisecond 35 | for { 36 | if f() { 37 | return true 38 | } 39 | 40 | if time.Now().After(timeoutEnd) { 41 | return false 42 | } 43 | 44 | time.Sleep(sleepFor) 45 | if sleepFor < maxSleep { 46 | sleepFor *= 2 47 | } 48 | } 49 | } 50 | 51 | // WaitWG waits for the given WaitGroup to be complete with a timeout 52 | // and returns whether the WaitGroup completed within the timeout. 53 | func WaitWG(wg *sync.WaitGroup, timeout time.Duration) bool { 54 | wgC := make(chan struct{}) 55 | 56 | go func() { 57 | wg.Wait() 58 | wgC <- struct{}{} 59 | }() 60 | select { 61 | case <-time.After(timeout): 62 | return false 63 | case <-wgC: 64 | return true 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /thirdparty/github.com/apache/thrift/lib/go/thrift/application_exception_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | package thrift 21 | 22 | import ( 23 | "testing" 24 | ) 25 | 26 | func TestTApplicationException(t *testing.T) { 27 | exc := NewTApplicationException(UNKNOWN_APPLICATION_EXCEPTION, "") 28 | if exc.Error() != "" { 29 | t.Fatalf("Expected empty string for exception but found '%s'", exc.Error()) 30 | } 31 | if exc.TypeId() != UNKNOWN_APPLICATION_EXCEPTION { 32 | t.Fatalf("Expected type UNKNOWN for exception but found '%s'", exc.TypeId()) 33 | } 34 | exc = NewTApplicationException(WRONG_METHOD_NAME, "junk_method") 35 | if exc.Error() != "junk_method" { 36 | t.Fatalf("Expected 'junk_method' for exception but found '%s'", exc.Error()) 37 | } 38 | if exc.TypeId() != WRONG_METHOD_NAME { 39 | t.Fatalf("Expected type WRONG_METHOD_NAME for exception but found '%s'", exc.TypeId()) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /thirdparty/github.com/apache/thrift/lib/go/thrift/binary_protocol_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | package thrift 21 | 22 | import ( 23 | "testing" 24 | ) 25 | 26 | func TestReadWriteBinaryProtocol(t *testing.T) { 27 | ReadWriteProtocolTest(t, NewTBinaryProtocolFactoryDefault()) 28 | } 29 | -------------------------------------------------------------------------------- /thirdparty/github.com/apache/thrift/lib/go/thrift/buffered_transport_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | package thrift 21 | 22 | import ( 23 | "testing" 24 | ) 25 | 26 | func TestBufferedTransport(t *testing.T) { 27 | trans := NewTBufferedTransport(NewTMemoryBuffer(), 10240) 28 | TransportTest(t, trans, trans) 29 | } 30 | -------------------------------------------------------------------------------- /thirdparty/github.com/apache/thrift/lib/go/thrift/compact_protocol_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | package thrift 21 | 22 | import ( 23 | "bytes" 24 | "testing" 25 | ) 26 | 27 | func TestReadWriteCompactProtocol(t *testing.T) { 28 | ReadWriteProtocolTest(t, NewTCompactProtocolFactory()) 29 | transports := []TTransport{ 30 | NewTMemoryBuffer(), 31 | NewStreamTransportRW(bytes.NewBuffer(make([]byte, 0, 16384))), 32 | NewTFramedTransport(NewTMemoryBuffer()), 33 | } 34 | for _, trans := range transports { 35 | p := NewTCompactProtocol(trans); 36 | ReadWriteBool(t, p, trans); 37 | p = NewTCompactProtocol(trans); 38 | ReadWriteByte(t, p, trans); 39 | p = NewTCompactProtocol(trans); 40 | ReadWriteI16(t, p, trans); 41 | p = NewTCompactProtocol(trans); 42 | ReadWriteI32(t, p, trans); 43 | p = NewTCompactProtocol(trans); 44 | ReadWriteI64(t, p, trans); 45 | p = NewTCompactProtocol(trans); 46 | ReadWriteDouble(t, p, trans); 47 | p = NewTCompactProtocol(trans); 48 | ReadWriteString(t, p, trans); 49 | p = NewTCompactProtocol(trans); 50 | ReadWriteBinary(t, p, trans); 51 | trans.Close(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /thirdparty/github.com/apache/thrift/lib/go/thrift/deserializer.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | package thrift 21 | 22 | type TDeserializer struct { 23 | Transport TTransport 24 | Protocol TProtocol 25 | } 26 | 27 | func NewTDeserializer() *TDeserializer { 28 | var transport TTransport 29 | transport = NewTMemoryBufferLen(1024) 30 | 31 | protocol := NewTBinaryProtocolFactoryDefault().GetProtocol(transport) 32 | 33 | return &TDeserializer{ 34 | transport, 35 | protocol} 36 | } 37 | 38 | func (t *TDeserializer) ReadString(msg TStruct, s string) (err error) { 39 | err = nil 40 | if _, err = t.Transport.Write([]byte(s)); err != nil { 41 | return 42 | } 43 | if err = msg.Read(t.Protocol); err != nil { 44 | return 45 | } 46 | return 47 | } 48 | 49 | func (t *TDeserializer) Read(msg TStruct, b []byte) (err error) { 50 | err = nil 51 | if _, err = t.Transport.Write(b); err != nil { 52 | return 53 | } 54 | if err = msg.Read(t.Protocol); err != nil { 55 | return 56 | } 57 | return 58 | } 59 | -------------------------------------------------------------------------------- /thirdparty/github.com/apache/thrift/lib/go/thrift/exception.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | package thrift 21 | 22 | import ( 23 | "errors" 24 | ) 25 | 26 | // Generic Thrift exception 27 | type TException interface { 28 | error 29 | } 30 | 31 | // Prepends additional information to an error without losing the Thrift exception interface 32 | func PrependError(prepend string, err error) error { 33 | if t, ok := err.(TTransportException); ok { 34 | return NewTTransportException(t.TypeId(), prepend+t.Error()) 35 | } 36 | if t, ok := err.(TProtocolException); ok { 37 | return NewTProtocolExceptionWithType(t.TypeId(), errors.New(prepend+err.Error())) 38 | } 39 | if t, ok := err.(TApplicationException); ok { 40 | return NewTApplicationException(t.TypeId(), prepend+t.Error()) 41 | } 42 | 43 | return errors.New(prepend + err.Error()) 44 | } 45 | -------------------------------------------------------------------------------- /thirdparty/github.com/apache/thrift/lib/go/thrift/field.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | package thrift 21 | 22 | // Helper class that encapsulates field metadata. 23 | type field struct { 24 | name string 25 | typeId TType 26 | id int 27 | } 28 | 29 | func newField(n string, t TType, i int) *field { 30 | return &field{name: n, typeId: t, id: i} 31 | } 32 | 33 | func (p *field) Name() string { 34 | if p == nil { 35 | return "" 36 | } 37 | return p.name 38 | } 39 | 40 | func (p *field) TypeId() TType { 41 | if p == nil { 42 | return TType(VOID) 43 | } 44 | return p.typeId 45 | } 46 | 47 | func (p *field) Id() int { 48 | if p == nil { 49 | return -1 50 | } 51 | return p.id 52 | } 53 | 54 | func (p *field) String() string { 55 | if p == nil { 56 | return "" 57 | } 58 | return "" 59 | } 60 | 61 | var ANONYMOUS_FIELD *field 62 | 63 | type fieldSlice []field 64 | 65 | func (p fieldSlice) Len() int { 66 | return len(p) 67 | } 68 | 69 | func (p fieldSlice) Less(i, j int) bool { 70 | return p[i].Id() < p[j].Id() 71 | } 72 | 73 | func (p fieldSlice) Swap(i, j int) { 74 | p[i], p[j] = p[j], p[i] 75 | } 76 | 77 | func init() { 78 | ANONYMOUS_FIELD = newField("", STOP, 0) 79 | } 80 | -------------------------------------------------------------------------------- /thirdparty/github.com/apache/thrift/lib/go/thrift/framed_transport_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | package thrift 21 | 22 | import ( 23 | "testing" 24 | ) 25 | 26 | func TestFramedTransport(t *testing.T) { 27 | trans := NewTFramedTransport(NewTMemoryBuffer()) 28 | TransportTest(t, trans, trans) 29 | } 30 | -------------------------------------------------------------------------------- /thirdparty/github.com/apache/thrift/lib/go/thrift/http_transport.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | package thrift 21 | 22 | import "net/http" 23 | 24 | // NewThriftHandlerFunc is a function that create a ready to use Apache Thrift Handler function 25 | func NewThriftHandlerFunc(processor TProcessor, 26 | inPfactory, outPfactory TProtocolFactory) func(w http.ResponseWriter, r *http.Request) { 27 | 28 | return func(w http.ResponseWriter, r *http.Request) { 29 | w.Header().Add("Content-Type", "application/x-thrift") 30 | 31 | transport := NewStreamTransport(r.Body, w) 32 | processor.Process(inPfactory.GetProtocol(transport), outPfactory.GetProtocol(transport)) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /thirdparty/github.com/apache/thrift/lib/go/thrift/iostream_transport_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | package thrift 21 | 22 | import ( 23 | "bytes" 24 | "testing" 25 | ) 26 | 27 | func TestStreamTransport(t *testing.T) { 28 | trans := NewStreamTransportRW(bytes.NewBuffer(make([]byte, 0, 1024))) 29 | TransportTest(t, trans, trans) 30 | } 31 | 32 | func TestStreamTransportOpenClose(t *testing.T) { 33 | trans := NewStreamTransportRW(bytes.NewBuffer(make([]byte, 0, 1024))) 34 | if !trans.IsOpen() { 35 | t.Fatal("StreamTransport should be already open") 36 | } 37 | if trans.Open() == nil { 38 | t.Fatal("StreamTransport should return error when open twice") 39 | } 40 | if trans.Close() != nil { 41 | t.Fatal("StreamTransport should not return error when closing open transport") 42 | } 43 | if trans.IsOpen() { 44 | t.Fatal("StreamTransport should not be open after close") 45 | } 46 | if trans.Close() == nil { 47 | t.Fatal("StreamTransport should return error when closing a non open transport") 48 | } 49 | if trans.Open() == nil { 50 | t.Fatal("StreamTransport should not be able to reopen") 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /thirdparty/github.com/apache/thrift/lib/go/thrift/memory_buffer.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | package thrift 21 | 22 | import ( 23 | "bytes" 24 | ) 25 | 26 | // Memory buffer-based implementation of the TTransport interface. 27 | type TMemoryBuffer struct { 28 | *bytes.Buffer 29 | size int 30 | } 31 | 32 | type TMemoryBufferTransportFactory struct { 33 | size int 34 | } 35 | 36 | func (p *TMemoryBufferTransportFactory) GetTransport(trans TTransport) TTransport { 37 | if trans != nil { 38 | t, ok := trans.(*TMemoryBuffer) 39 | if ok && t.size > 0 { 40 | return NewTMemoryBufferLen(t.size) 41 | } 42 | } 43 | return NewTMemoryBufferLen(p.size) 44 | } 45 | 46 | func NewTMemoryBufferTransportFactory(size int) *TMemoryBufferTransportFactory { 47 | return &TMemoryBufferTransportFactory{size: size} 48 | } 49 | 50 | func NewTMemoryBuffer() *TMemoryBuffer { 51 | return &TMemoryBuffer{Buffer: &bytes.Buffer{}, size: 0} 52 | } 53 | 54 | func NewTMemoryBufferLen(size int) *TMemoryBuffer { 55 | buf := make([]byte, 0, size) 56 | return &TMemoryBuffer{Buffer: bytes.NewBuffer(buf), size: size} 57 | } 58 | 59 | func (p *TMemoryBuffer) IsOpen() bool { 60 | return true 61 | } 62 | 63 | func (p *TMemoryBuffer) Open() error { 64 | return nil 65 | } 66 | 67 | func (p *TMemoryBuffer) Close() error { 68 | p.Buffer.Reset() 69 | return nil 70 | } 71 | 72 | // Flushing a memory buffer is a no-op 73 | func (p *TMemoryBuffer) Flush() error { 74 | return nil 75 | } 76 | 77 | func (p *TMemoryBuffer) RemainingBytes() (num_bytes uint64) { 78 | return uint64(p.Buffer.Len()) 79 | } 80 | -------------------------------------------------------------------------------- /thirdparty/github.com/apache/thrift/lib/go/thrift/memory_buffer_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | package thrift 21 | 22 | import ( 23 | "testing" 24 | ) 25 | 26 | func TestMemoryBuffer(t *testing.T) { 27 | trans := NewTMemoryBufferLen(1024) 28 | TransportTest(t, trans, trans) 29 | } 30 | -------------------------------------------------------------------------------- /thirdparty/github.com/apache/thrift/lib/go/thrift/messagetype.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | package thrift 21 | 22 | // Message type constants in the Thrift protocol. 23 | type TMessageType int32 24 | 25 | const ( 26 | INVALID_TMESSAGE_TYPE TMessageType = 0 27 | CALL TMessageType = 1 28 | REPLY TMessageType = 2 29 | EXCEPTION TMessageType = 3 30 | ONEWAY TMessageType = 4 31 | ) 32 | -------------------------------------------------------------------------------- /thirdparty/github.com/apache/thrift/lib/go/thrift/pointerize.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | package thrift 21 | 22 | /////////////////////////////////////////////////////////////////////////////// 23 | // This file is home to helpers that convert from various base types to 24 | // respective pointer types. This is necessary because Go does not permit 25 | // references to constants, nor can a pointer type to base type be allocated 26 | // and initialized in a single expression. 27 | // 28 | // E.g., this is not allowed: 29 | // 30 | // var ip *int = &5 31 | // 32 | // But this *is* allowed: 33 | // 34 | // func IntPtr(i int) *int { return &i } 35 | // var ip *int = IntPtr(5) 36 | // 37 | // Since pointers to base types are commonplace as [optional] fields in 38 | // exported thrift structs, we factor such helpers here. 39 | /////////////////////////////////////////////////////////////////////////////// 40 | 41 | func Float32Ptr(v float32) *float32 { return &v } 42 | func Float64Ptr(v float64) *float64 { return &v } 43 | func IntPtr(v int) *int { return &v } 44 | func Int32Ptr(v int32) *int32 { return &v } 45 | func Int64Ptr(v int64) *int64 { return &v } 46 | func StringPtr(v string) *string { return &v } 47 | func Uint32Ptr(v uint32) *uint32 { return &v } 48 | func Uint64Ptr(v uint64) *uint64 { return &v } 49 | func BoolPtr(v bool) *bool { return &v } 50 | func ByteSlicePtr(v []byte) *[]byte { return &v } 51 | -------------------------------------------------------------------------------- /thirdparty/github.com/apache/thrift/lib/go/thrift/processor.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | package thrift 21 | 22 | // A processor is a generic object which operates upon an input stream and 23 | // writes to some output stream. 24 | type TProcessor interface { 25 | Process(in, out TProtocol) (bool, TException) 26 | } 27 | 28 | type TProcessorFunction interface { 29 | Process(seqId int32, in, out TProtocol) (bool, TException) 30 | } 31 | -------------------------------------------------------------------------------- /thirdparty/github.com/apache/thrift/lib/go/thrift/processor_factory.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | package thrift 21 | 22 | // The default processor factory just returns a singleton 23 | // instance. 24 | type TProcessorFactory interface { 25 | GetProcessor(trans TTransport) TProcessor 26 | } 27 | 28 | type tProcessorFactory struct { 29 | processor TProcessor 30 | } 31 | 32 | func NewTProcessorFactory(p TProcessor) TProcessorFactory { 33 | return &tProcessorFactory{processor: p} 34 | } 35 | 36 | func (p *tProcessorFactory) GetProcessor(trans TTransport) TProcessor { 37 | return p.processor 38 | } 39 | 40 | /** 41 | * The default processor factory just returns a singleton 42 | * instance. 43 | */ 44 | type TProcessorFunctionFactory interface { 45 | GetProcessorFunction(trans TTransport) TProcessorFunction 46 | } 47 | 48 | type tProcessorFunctionFactory struct { 49 | processor TProcessorFunction 50 | } 51 | 52 | func NewTProcessorFunctionFactory(p TProcessorFunction) TProcessorFunctionFactory { 53 | return &tProcessorFunctionFactory{processor: p} 54 | } 55 | 56 | func (p *tProcessorFunctionFactory) GetProcessorFunction(trans TTransport) TProcessorFunction { 57 | return p.processor 58 | } 59 | -------------------------------------------------------------------------------- /thirdparty/github.com/apache/thrift/lib/go/thrift/protocol_exception.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | package thrift 21 | 22 | import ( 23 | "encoding/base64" 24 | ) 25 | 26 | // Thrift Protocol exception 27 | type TProtocolException interface { 28 | TException 29 | TypeId() int 30 | } 31 | 32 | const ( 33 | UNKNOWN_PROTOCOL_EXCEPTION = 0 34 | INVALID_DATA = 1 35 | NEGATIVE_SIZE = 2 36 | SIZE_LIMIT = 3 37 | BAD_VERSION = 4 38 | NOT_IMPLEMENTED = 5 39 | DEPTH_LIMIT = 6 40 | ) 41 | 42 | type tProtocolException struct { 43 | typeId int 44 | message string 45 | } 46 | 47 | func (p *tProtocolException) TypeId() int { 48 | return p.typeId 49 | } 50 | 51 | func (p *tProtocolException) String() string { 52 | return p.message 53 | } 54 | 55 | func (p *tProtocolException) Error() string { 56 | return p.message 57 | } 58 | 59 | func NewTProtocolException(err error) TProtocolException { 60 | if err == nil { 61 | return nil 62 | } 63 | if e,ok := err.(TProtocolException); ok { 64 | return e 65 | } 66 | if _, ok := err.(base64.CorruptInputError); ok { 67 | return &tProtocolException{INVALID_DATA, err.Error()} 68 | } 69 | return &tProtocolException{UNKNOWN_PROTOCOL_EXCEPTION, err.Error()} 70 | } 71 | 72 | func NewTProtocolExceptionWithType(errType int, err error) TProtocolException { 73 | if err == nil { 74 | return nil 75 | } 76 | return &tProtocolException{errType, err.Error()} 77 | } 78 | 79 | -------------------------------------------------------------------------------- /thirdparty/github.com/apache/thrift/lib/go/thrift/protocol_factory.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | package thrift 21 | 22 | // Factory interface for constructing protocol instances. 23 | type TProtocolFactory interface { 24 | GetProtocol(trans TTransport) TProtocol 25 | } 26 | -------------------------------------------------------------------------------- /thirdparty/github.com/apache/thrift/lib/go/thrift/rich_transport.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | package thrift 21 | 22 | import "io" 23 | 24 | type RichTransport struct { 25 | TTransport 26 | } 27 | 28 | // Wraps Transport to provide TRichTransport interface 29 | func NewTRichTransport(trans TTransport) *RichTransport { 30 | return &RichTransport{trans} 31 | } 32 | 33 | func (r *RichTransport) ReadByte() (c byte, err error) { 34 | return readByte(r.TTransport) 35 | } 36 | 37 | func (r *RichTransport) WriteByte(c byte) error { 38 | return writeByte(r.TTransport, c) 39 | } 40 | 41 | func (r *RichTransport) WriteString(s string) (n int, err error) { 42 | return r.Write([]byte(s)) 43 | } 44 | 45 | func (r *RichTransport) RemainingBytes() (num_bytes uint64) { 46 | return r.TTransport.RemainingBytes() 47 | } 48 | 49 | func readByte(r io.Reader) (c byte, err error) { 50 | v := [1]byte{0} 51 | n, err := r.Read(v[0:1]) 52 | if n > 0 && (err == nil || err == io.EOF) { 53 | return v[0], nil 54 | } 55 | if n > 0 && err != nil { 56 | return v[0], err 57 | } 58 | if err != nil { 59 | return 0, err 60 | } 61 | return v[0], nil 62 | } 63 | 64 | func writeByte(w io.Writer, c byte) error { 65 | v := [1]byte{c} 66 | _, err := w.Write(v[0:1]) 67 | return err 68 | } 69 | 70 | -------------------------------------------------------------------------------- /thirdparty/github.com/apache/thrift/lib/go/thrift/serializer.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | package thrift 21 | 22 | type TSerializer struct { 23 | Transport *TMemoryBuffer 24 | Protocol TProtocol 25 | } 26 | 27 | type TStruct interface { 28 | Write(p TProtocol) error 29 | Read(p TProtocol) error 30 | } 31 | 32 | func NewTSerializer() *TSerializer { 33 | transport := NewTMemoryBufferLen(1024) 34 | protocol := NewTBinaryProtocolFactoryDefault().GetProtocol(transport) 35 | 36 | return &TSerializer{ 37 | transport, 38 | protocol} 39 | } 40 | 41 | func (t *TSerializer) WriteString(msg TStruct) (s string, err error) { 42 | t.Transport.Reset() 43 | 44 | if err = msg.Write(t.Protocol); err != nil { 45 | return 46 | } 47 | 48 | if err = t.Protocol.Flush(); err != nil { 49 | return 50 | } 51 | if err = t.Transport.Flush(); err != nil { 52 | return 53 | } 54 | 55 | return t.Transport.String(), nil 56 | } 57 | 58 | func (t *TSerializer) Write(msg TStruct) (b []byte, err error) { 59 | t.Transport.Reset() 60 | 61 | if err = msg.Write(t.Protocol); err != nil { 62 | return 63 | } 64 | 65 | if err = t.Protocol.Flush(); err != nil { 66 | return 67 | } 68 | 69 | if err = t.Transport.Flush(); err != nil { 70 | return 71 | } 72 | 73 | b = append(b, t.Transport.Bytes()...) 74 | return 75 | } 76 | -------------------------------------------------------------------------------- /thirdparty/github.com/apache/thrift/lib/go/thrift/server.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | package thrift 21 | 22 | type TServer interface { 23 | ProcessorFactory() TProcessorFactory 24 | ServerTransport() TServerTransport 25 | InputTransportFactory() TTransportFactory 26 | OutputTransportFactory() TTransportFactory 27 | InputProtocolFactory() TProtocolFactory 28 | OutputProtocolFactory() TProtocolFactory 29 | 30 | // Starts the server 31 | Serve() error 32 | // Stops the server. This is optional on a per-implementation basis. Not 33 | // all servers are required to be cleanly stoppable. 34 | Stop() error 35 | } 36 | -------------------------------------------------------------------------------- /thirdparty/github.com/apache/thrift/lib/go/thrift/server_socket_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | package thrift 21 | 22 | import ( 23 | "fmt" 24 | "testing" 25 | ) 26 | 27 | func TestSocketIsntListeningAfterInterrupt(t *testing.T) { 28 | host := "127.0.0.1" 29 | port := 9090 30 | addr := fmt.Sprintf("%s:%d", host, port) 31 | 32 | socket := CreateServerSocket(t, addr) 33 | socket.Listen() 34 | socket.Interrupt() 35 | 36 | newSocket := CreateServerSocket(t, addr) 37 | err := newSocket.Listen() 38 | defer newSocket.Interrupt() 39 | if err != nil { 40 | t.Fatalf("Failed to rebinds: %s", err) 41 | } 42 | } 43 | 44 | func CreateServerSocket(t *testing.T, addr string) *TServerSocket { 45 | socket, err := NewTServerSocket(addr) 46 | if err != nil { 47 | t.Fatalf("Failed to create server socket: %s", err) 48 | } 49 | return socket 50 | } 51 | -------------------------------------------------------------------------------- /thirdparty/github.com/apache/thrift/lib/go/thrift/server_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | package thrift 21 | 22 | import ( 23 | "testing" 24 | ) 25 | 26 | func TestNothing(t *testing.T) { 27 | 28 | } 29 | -------------------------------------------------------------------------------- /thirdparty/github.com/apache/thrift/lib/go/thrift/server_transport.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | package thrift 21 | 22 | // Server transport. Object which provides client transports. 23 | type TServerTransport interface { 24 | Listen() error 25 | Accept() (TTransport, error) 26 | Close() error 27 | 28 | // Optional method implementation. This signals to the server transport 29 | // that it should break out of any accept() or listen() that it is currently 30 | // blocked on. This method, if implemented, MUST be thread safe, as it may 31 | // be called from a different thread context than the other TServerTransport 32 | // methods. 33 | Interrupt() error 34 | } 35 | -------------------------------------------------------------------------------- /thirdparty/github.com/apache/thrift/lib/go/thrift/transport.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | package thrift 21 | 22 | import ( 23 | "errors" 24 | "io" 25 | ) 26 | 27 | var errTransportInterrupted = errors.New("Transport Interrupted") 28 | 29 | type Flusher interface { 30 | Flush() (err error) 31 | } 32 | 33 | type ReadSizeProvider interface { 34 | RemainingBytes() (num_bytes uint64) 35 | } 36 | 37 | 38 | // Encapsulates the I/O layer 39 | type TTransport interface { 40 | io.ReadWriteCloser 41 | Flusher 42 | ReadSizeProvider 43 | 44 | // Opens the transport for communication 45 | Open() error 46 | 47 | // Returns true if the transport is open 48 | IsOpen() bool 49 | } 50 | 51 | type stringWriter interface { 52 | WriteString(s string) (n int, err error) 53 | } 54 | 55 | 56 | // This is "enchanced" transport with extra capabilities. You need to use one of these 57 | // to construct protocol. 58 | // Notably, TSocket does not implement this interface, and it is always a mistake to use 59 | // TSocket directly in protocol. 60 | type TRichTransport interface { 61 | io.ReadWriter 62 | io.ByteReader 63 | io.ByteWriter 64 | stringWriter 65 | Flusher 66 | ReadSizeProvider 67 | } 68 | 69 | -------------------------------------------------------------------------------- /thirdparty/github.com/apache/thrift/lib/go/thrift/transport_exception_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | package thrift 21 | 22 | import ( 23 | "fmt" 24 | "io" 25 | 26 | "testing" 27 | ) 28 | 29 | type timeout struct{ timedout bool } 30 | 31 | func (t *timeout) Timeout() bool { 32 | return t.timedout 33 | } 34 | 35 | func (t *timeout) Error() string { 36 | return fmt.Sprintf("Timeout: %v", t.timedout) 37 | } 38 | 39 | func TestTExceptionTimeout(t *testing.T) { 40 | timeout := &timeout{true} 41 | exception := NewTTransportExceptionFromError(timeout) 42 | if timeout.Error() != exception.Error() { 43 | t.Fatalf("Error did not match: expected %q, got %q", timeout.Error(), exception.Error()) 44 | } 45 | 46 | if exception.TypeId() != TIMED_OUT { 47 | t.Fatalf("TypeId was not TIMED_OUT: expected %v, got %v", TIMED_OUT, exception.TypeId()) 48 | } 49 | } 50 | 51 | func TestTExceptionEOF(t *testing.T) { 52 | exception := NewTTransportExceptionFromError(io.EOF) 53 | if io.EOF.Error() != exception.Error() { 54 | t.Fatalf("Error did not match: expected %q, got %q", io.EOF.Error(), exception.Error()) 55 | } 56 | 57 | if exception.TypeId() != END_OF_FILE { 58 | t.Fatalf("TypeId was not END_OF_FILE: expected %v, got %v", END_OF_FILE, exception.TypeId()) 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /thirdparty/github.com/apache/thrift/lib/go/thrift/transport_factory.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | package thrift 21 | 22 | // Factory class used to create wrapped instance of Transports. 23 | // This is used primarily in servers, which get Transports from 24 | // a ServerTransport and then may want to mutate them (i.e. create 25 | // a BufferedTransport from the underlying base transport) 26 | type TTransportFactory interface { 27 | GetTransport(trans TTransport) TTransport 28 | } 29 | 30 | type tTransportFactory struct{} 31 | 32 | // Return a wrapped instance of the base Transport. 33 | func (p *tTransportFactory) GetTransport(trans TTransport) TTransport { 34 | return trans 35 | } 36 | 37 | func NewTTransportFactory() TTransportFactory { 38 | return &tTransportFactory{} 39 | } 40 | -------------------------------------------------------------------------------- /thirdparty/github.com/apache/thrift/lib/go/thrift/type.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | package thrift 21 | 22 | // Type constants in the Thrift protocol 23 | type TType byte 24 | 25 | const ( 26 | STOP = 0 27 | VOID = 1 28 | BOOL = 2 29 | BYTE = 3 30 | I08 = 3 31 | DOUBLE = 4 32 | I16 = 6 33 | I32 = 8 34 | I64 = 10 35 | STRING = 11 36 | UTF7 = 11 37 | STRUCT = 12 38 | MAP = 13 39 | SET = 14 40 | LIST = 15 41 | UTF8 = 16 42 | UTF16 = 17 43 | //BINARY = 18 wrong and unusued 44 | ) 45 | 46 | var typeNames = map[int]string{ 47 | STOP: "STOP", 48 | VOID: "VOID", 49 | BOOL: "BOOL", 50 | BYTE: "BYTE", 51 | DOUBLE: "DOUBLE", 52 | I16: "I16", 53 | I32: "I32", 54 | I64: "I64", 55 | STRING: "STRING", 56 | STRUCT: "STRUCT", 57 | MAP: "MAP", 58 | SET: "SET", 59 | LIST: "LIST", 60 | UTF8: "UTF8", 61 | UTF16: "UTF16", 62 | } 63 | 64 | func (p TType) String() string { 65 | if s, ok := typeNames[int(p)]; ok { 66 | return s 67 | } 68 | return "Unknown" 69 | } 70 | -------------------------------------------------------------------------------- /thirdparty/github.com/apache/thrift/lib/go/thrift/zlib_transport_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | 20 | package thrift 21 | 22 | import ( 23 | "compress/zlib" 24 | "testing" 25 | ) 26 | 27 | func TestZlibTransport(t *testing.T) { 28 | trans, err := NewTZlibTransport(NewTMemoryBuffer(), zlib.BestCompression) 29 | if err != nil { 30 | t.Fatal(err) 31 | } 32 | TransportTest(t, trans, trans) 33 | } 34 | -------------------------------------------------------------------------------- /thrift/context.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package thrift 22 | 23 | import ( 24 | "time" 25 | 26 | "github.com/uber/tchannel-go" 27 | "golang.org/x/net/context" 28 | ) 29 | 30 | // Context is a Thrift Context which contains request and response headers. 31 | type Context tchannel.ContextWithHeaders 32 | 33 | // NewContext returns a Context that can be used to make Thrift calls. 34 | func NewContext(timeout time.Duration) (Context, context.CancelFunc) { 35 | ctx, cancel := tchannel.NewContext(timeout) 36 | return Wrap(ctx), cancel 37 | } 38 | 39 | // Wrap returns a Thrift Context that wraps around a Context. 40 | func Wrap(ctx context.Context) Context { 41 | return tchannel.Wrap(ctx) 42 | } 43 | 44 | // WithHeaders returns a Context that can be used to make a call with request headers. 45 | func WithHeaders(ctx context.Context, headers map[string]string) Context { 46 | return tchannel.WrapWithHeaders(ctx, headers) 47 | } 48 | -------------------------------------------------------------------------------- /thrift/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | /* 22 | Package thrift adds support to use Thrift services over TChannel. 23 | 24 | To start listening to a Thrift service using TChannel, create the channel, 25 | and register the service using: 26 | 27 | server := thrift.NewServer(tchan) 28 | server.Register(gen.NewTChan[SERVICE]Server(handler) 29 | 30 | // Any number of services can be registered on the same Thrift server. 31 | server.Register(gen.NewTChan[SERVICE2]Server(handler) 32 | 33 | To use a Thrift client use the generated TChan client: 34 | 35 | thriftClient := thrift.NewClient(ch, "hyperbahnService", nil) 36 | client := gen.NewTChan[SERVICE]Client(thriftClient) 37 | 38 | // Any number of service clients can be made using the same Thrift client. 39 | client2 := gen.NewTChan[SERVICE2]Client(thriftClient) 40 | 41 | This client can be used similar to a standard Thrift client, except a Context 42 | is passed with options (such as timeout). 43 | 44 | TODO(prashant): Add and document header support. 45 | */ 46 | package thrift 47 | -------------------------------------------------------------------------------- /thrift/gen-go/meta/constants.go: -------------------------------------------------------------------------------- 1 | // Autogenerated by Thrift Compiler (1.0.0-dev) 2 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 3 | 4 | package meta 5 | 6 | import ( 7 | "bytes" 8 | "fmt" 9 | "github.com/uber/tchannel-go/thirdparty/github.com/apache/thrift/lib/go/thrift" 10 | ) 11 | 12 | // (needed to ensure safety because of naive import list construction.) 13 | var _ = thrift.ZERO 14 | var _ = fmt.Printf 15 | var _ = bytes.Equal 16 | 17 | func init() { 18 | } 19 | -------------------------------------------------------------------------------- /thrift/gen-go/test/constants.go: -------------------------------------------------------------------------------- 1 | // Autogenerated by Thrift Compiler (1.0.0-dev) 2 | // DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING 3 | 4 | package test 5 | 6 | import ( 7 | "bytes" 8 | "fmt" 9 | "github.com/uber/tchannel-go/thirdparty/github.com/apache/thrift/lib/go/thrift" 10 | ) 11 | 12 | // (needed to ensure safety because of naive import list construction.) 13 | var _ = thrift.ZERO 14 | var _ = fmt.Printf 15 | var _ = bytes.Equal 16 | 17 | func init() { 18 | } 19 | -------------------------------------------------------------------------------- /thrift/meta.thrift: -------------------------------------------------------------------------------- 1 | // The HealthState provides additional information when the 2 | // health endpoint returns !ok. 3 | enum HealthState { 4 | REFUSING = 0, 5 | ACCEPTING = 1, 6 | STOPPING = 2, 7 | STOPPED = 3, 8 | } 9 | 10 | // The HealthRequestType is the type of health check, as a process may want to 11 | // return that it's running, but not ready for traffic. 12 | enum HealthRequestType { 13 | // PROCESS indicates that the health check is for checking that 14 | // the process is up. Handlers should always return "ok". 15 | PROCESS = 0, 16 | 17 | // TRAFFIC indicates that the health check is for checking whether 18 | // the process wants to receive traffic. The process may want to reject 19 | // traffic due to warmup, or before shutdown to avoid in-flight requests 20 | // when the process exits. 21 | TRAFFIC = 1, 22 | } 23 | 24 | struct HealthRequest { 25 | 1: optional HealthRequestType type 26 | } 27 | 28 | struct HealthStatus { 29 | 1: required bool ok 30 | 2: optional string message 31 | 3: optional HealthState state 32 | } 33 | 34 | typedef string filename 35 | 36 | struct ThriftIDLs { 37 | // map: filename -> contents 38 | 1: required map idls 39 | // the entry IDL that imports others 40 | 2: required filename entryPoint 41 | } 42 | 43 | struct VersionInfo { 44 | // short string naming the implementation language 45 | 1: required string language 46 | // language-specific version string representing runtime or build chain 47 | 2: required string language_version 48 | // semver version indicating the version of the tchannel library 49 | 3: required string version 50 | } 51 | 52 | service Meta { 53 | // All arguments are optional. The default is a PROCESS health request. 54 | HealthStatus health(1: HealthRequest hr) 55 | 56 | ThriftIDLs thriftIDL() 57 | VersionInfo versionInfo() 58 | } 59 | -------------------------------------------------------------------------------- /thrift/mocks/TChanMeta.go: -------------------------------------------------------------------------------- 1 | package mocks 2 | 3 | import "github.com/uber/tchannel-go/thrift/gen-go/meta" 4 | import "github.com/stretchr/testify/mock" 5 | 6 | import "github.com/uber/tchannel-go/thrift" 7 | 8 | type TChanMeta struct { 9 | mock.Mock 10 | } 11 | 12 | func (_m *TChanMeta) Health(ctx thrift.Context) (*meta.HealthStatus, error) { 13 | ret := _m.Called(ctx) 14 | 15 | var r0 *meta.HealthStatus 16 | if rf, ok := ret.Get(0).(func(thrift.Context) *meta.HealthStatus); ok { 17 | r0 = rf(ctx) 18 | } else { 19 | if ret.Get(0) != nil { 20 | r0 = ret.Get(0).(*meta.HealthStatus) 21 | } 22 | } 23 | 24 | var r1 error 25 | if rf, ok := ret.Get(1).(func(thrift.Context) error); ok { 26 | r1 = rf(ctx) 27 | } else { 28 | r1 = ret.Error(1) 29 | } 30 | 31 | return r0, r1 32 | } 33 | -------------------------------------------------------------------------------- /thrift/mocks/TChanSecondService.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package mocks 22 | 23 | import "github.com/stretchr/testify/mock" 24 | 25 | import "github.com/uber/tchannel-go/thrift" 26 | 27 | type TChanSecondService struct { 28 | mock.Mock 29 | } 30 | 31 | func (_m *TChanSecondService) Echo(_ctx thrift.Context, _arg string) (string, error) { 32 | ret := _m.Called(_ctx, _arg) 33 | 34 | var r0 string 35 | if rf, ok := ret.Get(0).(func(thrift.Context, string) string); ok { 36 | r0 = rf(_ctx, _arg) 37 | } else { 38 | r0 = ret.Get(0).(string) 39 | } 40 | 41 | var r1 error 42 | if rf, ok := ret.Get(1).(func(thrift.Context, string) error); ok { 43 | r1 = rf(_ctx, _arg) 44 | } else { 45 | r1 = ret.Error(1) 46 | } 47 | 48 | return r0, r1 49 | } 50 | -------------------------------------------------------------------------------- /thrift/options.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package thrift 22 | 23 | import ( 24 | "github.com/uber/tchannel-go/thirdparty/github.com/apache/thrift/lib/go/thrift" 25 | "golang.org/x/net/context" 26 | ) 27 | 28 | // RegisterOption is the interface for options to Register. 29 | type RegisterOption interface { 30 | Apply(h *handler) 31 | } 32 | 33 | // PostResponseCB registers a callback that is run after a response has been 34 | // compeltely processed (e.g. written to the channel). 35 | // This gives the server a chance to clean up resources from the response object 36 | type PostResponseCB func(ctx context.Context, method string, response thrift.TStruct) 37 | 38 | type optPostResponse PostResponseCB 39 | 40 | // OptPostResponse registers a PostResponseCB. 41 | func OptPostResponse(cb PostResponseCB) RegisterOption { 42 | return optPostResponse(cb) 43 | } 44 | 45 | func (o optPostResponse) Apply(h *handler) { 46 | h.postResponseCB = PostResponseCB(o) 47 | } 48 | -------------------------------------------------------------------------------- /thrift/struct.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package thrift 22 | 23 | import ( 24 | "io" 25 | 26 | "github.com/uber/tchannel-go/thirdparty/github.com/apache/thrift/lib/go/thrift" 27 | ) 28 | 29 | // WriteStruct writes the given Thrift struct to a writer. It pools TProtocols. 30 | func WriteStruct(writer io.Writer, s thrift.TStruct) error { 31 | wp := getProtocolWriter(writer) 32 | err := s.Write(wp.protocol) 33 | thriftProtocolPool.Put(wp) 34 | return err 35 | } 36 | 37 | // ReadStruct reads the given Thrift struct. It pools TProtocols. 38 | func ReadStruct(reader io.Reader, s thrift.TStruct) error { 39 | wp := getProtocolReader(reader) 40 | err := s.Read(wp.protocol) 41 | thriftProtocolPool.Put(wp) 42 | return err 43 | } 44 | -------------------------------------------------------------------------------- /thrift/test.thrift: -------------------------------------------------------------------------------- 1 | struct Data { 2 | 1: required bool b1, 3 | 2: required string s2, 4 | 3: required i32 i3 5 | } 6 | 7 | exception SimpleErr { 8 | 1: string message 9 | } 10 | 11 | exception NewErr { 12 | 1: string message 13 | } 14 | 15 | service SimpleService { 16 | Data Call(1: Data arg) 17 | void Simple() throws (1: SimpleErr simpleErr) 18 | void SimpleFuture() throws (1: SimpleErr simpleErr, 2: NewErr newErr) 19 | } 20 | 21 | service SecondService { 22 | string Echo(1: string arg) 23 | } 24 | 25 | struct HealthStatus { 26 | 1: required bool ok 27 | 2: optional string message 28 | } 29 | 30 | // Meta contains the old health endpoint without arguments. 31 | service Meta { 32 | HealthStatus health() 33 | } -------------------------------------------------------------------------------- /thrift/thrift-gen/gopath.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "fmt" 25 | "os" 26 | "path/filepath" 27 | ) 28 | 29 | // ResolveWithGoPath will resolve the filename relative to GOPATH and returns 30 | // the first file that exists, or an error otherwise. 31 | func ResolveWithGoPath(filename string) (string, error) { 32 | for _, file := range goPathCandidates(filename) { 33 | if _, err := os.Stat(file); !os.IsNotExist(err) { 34 | return file, nil 35 | } 36 | } 37 | 38 | return "", fmt.Errorf("file not found on GOPATH: %q", filename) 39 | } 40 | 41 | func goPathCandidates(filename string) []string { 42 | candidates := []string{filename} 43 | paths := filepath.SplitList(os.Getenv("GOPATH")) 44 | for _, path := range paths { 45 | resolvedFilename := filepath.Join(path, "src", filename) 46 | candidates = append(candidates, resolvedFilename) 47 | } 48 | 49 | return candidates 50 | } 51 | -------------------------------------------------------------------------------- /thrift/thrift-gen/include.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import "github.com/samuel/go-thrift/parser" 24 | 25 | // Include represents a single include statement in the Thrift file. 26 | type Include struct { 27 | key string 28 | file string 29 | pkg string 30 | } 31 | 32 | // Import returns the go import to use for this package. 33 | func (i *Include) Import() string { 34 | // TODO(prashant): Rename imports so they don't clash with standard imports. 35 | // This is not high priority since Apache thrift clashes already with "bytes" and "fmt". 36 | // which are the same imports we would clash with. 37 | return *packagePrefix + i.Package() 38 | } 39 | 40 | // Package returns the package selector for this package. 41 | func (i *Include) Package() string { 42 | return i.pkg 43 | } 44 | 45 | func createIncludes(parsed *parser.Thrift, all map[string]parseState) map[string]*Include { 46 | includes := make(map[string]*Include) 47 | for k, v := range parsed.Includes { 48 | included := all[v] 49 | includes[k] = &Include{ 50 | key: k, 51 | file: v, 52 | pkg: included.namespace, 53 | } 54 | } 55 | return includes 56 | } 57 | -------------------------------------------------------------------------------- /thrift/thrift-gen/test_files/binary.thrift: -------------------------------------------------------------------------------- 1 | typedef binary Z 2 | 3 | struct S { 4 | 1: binary s1 5 | 2: Z s2 6 | } 7 | 8 | service Test { 9 | binary M1(1: binary arg1) 10 | S M2(1: binary arg1, 2: S arg2) 11 | } 12 | -------------------------------------------------------------------------------- /thrift/thrift-gen/test_files/byte.thrift: -------------------------------------------------------------------------------- 1 | typedef byte Z 2 | 3 | struct S { 4 | 1: byte s1 5 | 2: Z s2 6 | } 7 | 8 | service Test { 9 | byte M1(1: byte arg1) 10 | S M2(1: byte arg1, 2: S arg2) 11 | } 12 | -------------------------------------------------------------------------------- /thrift/thrift-gen/test_files/gokeywords.thrift: -------------------------------------------------------------------------------- 1 | // Test to make sure that reserved names are handled correctly. 2 | 3 | exception Exception { 4 | 1: required string message 5 | } 6 | 7 | struct Result { 8 | 1: required string error 9 | 2: required i32 func 10 | 3: required i32 chan 11 | 4: required i32 result 12 | 5: required i64 newRole 13 | } 14 | 15 | service func { 16 | string func1() 17 | void func(1: i32 func) 18 | Result chan(1: i32 func, 2: i32 result) throws (1: Exception error) 19 | } 20 | -------------------------------------------------------------------------------- /thrift/thrift-gen/test_files/include_test/namespace/a/shared.thrift: -------------------------------------------------------------------------------- 1 | namespace go a_shared 2 | 3 | include "../b/shared.thrift" 4 | 5 | typedef shared.b_string a_string 6 | 7 | service AShared extends shared.BShared { 8 | bool healthA() 9 | } -------------------------------------------------------------------------------- /thrift/thrift-gen/test_files/include_test/namespace/b/shared.thrift: -------------------------------------------------------------------------------- 1 | namespace go b_shared 2 | 3 | typedef string b_string 4 | 5 | service BShared { 6 | bool healthB() 7 | } -------------------------------------------------------------------------------- /thrift/thrift-gen/test_files/include_test/namespace/namespace.thrift: -------------------------------------------------------------------------------- 1 | include "a/shared.thrift" 2 | 3 | service Foo extends shared.AShared { 4 | void Foo(1: shared.a_string str) 5 | } 6 | -------------------------------------------------------------------------------- /thrift/thrift-gen/test_files/include_test/simple/shared.thrift: -------------------------------------------------------------------------------- 1 | include "shared2.thrift" 2 | 3 | typedef string a_shared_string 4 | 5 | typedef shared2.a_shared2_string a_shared_string2 6 | 7 | typedef shared2.a_shared2_mystruct a_shared_mystruct2 8 | -------------------------------------------------------------------------------- /thrift/thrift-gen/test_files/include_test/simple/shared2.thrift: -------------------------------------------------------------------------------- 1 | typedef string a_shared2_string 2 | 3 | struct MyStruct { 4 | 1: string name 5 | } 6 | 7 | typedef MyStruct a_shared2_mystruct 8 | -------------------------------------------------------------------------------- /thrift/thrift-gen/test_files/include_test/simple/simple.thrift: -------------------------------------------------------------------------------- 1 | include "shared.thrift" 2 | include "shared2.thrift" 3 | 4 | service Foo { 5 | void Foo(1: shared.a_shared_string str, 2: shared.a_shared_string2 str2, 3: shared2.MyStruct str3) 6 | } 7 | -------------------------------------------------------------------------------- /thrift/thrift-gen/test_files/include_test/svc_extend/shared.thrift: -------------------------------------------------------------------------------- 1 | typedef string UUID 2 | 3 | 4 | struct Health { 5 | 1: bool ok 6 | } 7 | 8 | service FooBase { 9 | UUID getUUID() 10 | } 11 | -------------------------------------------------------------------------------- /thrift/thrift-gen/test_files/include_test/svc_extend/svc_extend.thrift: -------------------------------------------------------------------------------- 1 | include "shared.thrift" 2 | 3 | service Foo extends shared.FooBase { 4 | shared.UUID getMyUUID(1: shared.UUID uuid, 2: shared.Health health) 5 | shared.Health health(1: shared.UUID uuid, 2: shared.Health health) 6 | } 7 | 8 | //Go code: svc_extend/test.go 9 | // package svc_extend 10 | // var _ = TChanFoo(nil).GetMyUUID 11 | // var _ = TChanFoo(nil).Health 12 | // var _ = TChanFoo(nil).GetUUID 13 | -------------------------------------------------------------------------------- /thrift/thrift-gen/test_files/multi_test/file1.thrift: -------------------------------------------------------------------------------- 1 | include "file2.thrift" 2 | 3 | service Foo1 { 4 | void M() 5 | } 6 | -------------------------------------------------------------------------------- /thrift/thrift-gen/test_files/multi_test/file2.thrift: -------------------------------------------------------------------------------- 1 | 2 | service Foo2 { 3 | void M() 4 | } 5 | -------------------------------------------------------------------------------- /thrift/thrift-gen/test_files/service_extend.thrift: -------------------------------------------------------------------------------- 1 | struct S { 2 | 1: binary s1 3 | } 4 | 5 | service S1 { 6 | binary M1(1: binary bits) 7 | } 8 | 9 | service S2 extends S1 { 10 | S M2(1: optional S s, 2: optional i32 i) 11 | } 12 | 13 | service S3 extends S2 { 14 | void M3() 15 | } 16 | 17 | //Go code: service_extend/test.go 18 | // package service_extend 19 | // var _ = TChanS3(nil).M1 20 | // var _ = TChanS3(nil).M2 21 | // var _ = TChanS3(nil).M3 22 | // var _ int32 = S2M2Args{}.I 23 | -------------------------------------------------------------------------------- /thrift/thrift-gen/test_files/sets.thrift: -------------------------------------------------------------------------------- 1 | 2 | service Test { 3 | list getInts(1: list nums) 4 | set getIntSet(1: set nums) 5 | map getIntMap(1: map nums) 6 | } 7 | -------------------------------------------------------------------------------- /thrift/thrift-gen/test_files/test1.thrift: -------------------------------------------------------------------------------- 1 | 2 | struct FakeStruct { 3 | 1: i64 id 4 | 2: i64 user_id 5 | } 6 | 7 | service Fake { 8 | // Test initialisms in the method name (as well as name clashes). 9 | void id_get() 10 | void id() 11 | void get_id() 12 | void get_Id() 13 | void get_ID() 14 | 15 | // Test initialisms in parameter names. 16 | void initialisms_in_args1(1: string LoL_http_TEST_Name) 17 | void initialisms_in_args2(1: string user_id) 18 | void initialisms_in_args3(1: string id) 19 | 20 | 21 | // Test casing for method names 22 | void fAkE(1: i32 func, 2: i32 pkg, 3: FakeStruct fakeStruct) 23 | 24 | void MyArgs() 25 | void MyResult() 26 | } 27 | -------------------------------------------------------------------------------- /thrift/thrift-gen/test_files/typedefs.thrift: -------------------------------------------------------------------------------- 1 | 2 | typedef i64 X 3 | typedef X Z 4 | typedef X Y 5 | typedef i64 i 6 | typedef i64 func 7 | 8 | struct S { 9 | 1: X x 10 | 2: Y y 11 | 3: Z z 12 | } 13 | 14 | typedef S ST 15 | 16 | enum Operator 17 | { 18 | ADD = 1, 19 | SUBTRACT = 2 20 | } 21 | 22 | service Test { 23 | Y M1(1: X arg1, 2: i arg2) 24 | X M2(1: Y arg1) 25 | Z M3(1: X arg1) 26 | S M4(1: S arg1, 2: Operator op) 27 | 28 | // Thrift compiler is broken on this case. 29 | // ST M5(1: ST arg1, 2: S arg2) 30 | } 31 | -------------------------------------------------------------------------------- /thrift/thrift-gen/test_files/union.thrift: -------------------------------------------------------------------------------- 1 | union Constraint { 2 | 1: i32 intV 3 | 2: string stringV 4 | } 5 | 6 | // thrift-gen generated code assumes there is a service. 7 | service Test {} 8 | 9 | -------------------------------------------------------------------------------- /thrift/thrift-gen/validate.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "fmt" 25 | 26 | "github.com/samuel/go-thrift/parser" 27 | ) 28 | 29 | // Validate validates that the given spec is supported by thrift-gen. 30 | func Validate(svc *parser.Service) error { 31 | for _, m := range svc.Methods { 32 | if err := validateMethod(svc, m); err != nil { 33 | return err 34 | } 35 | } 36 | return nil 37 | } 38 | 39 | func validateMethod(svc *parser.Service, m *parser.Method) error { 40 | if m.Oneway { 41 | return fmt.Errorf("oneway methods are not supported: %s.%v", svc.Name, m.Name) 42 | } 43 | for _, arg := range m.Arguments { 44 | if arg.Optional { 45 | // Go treats argument structs as "Required" in the generated code interface. 46 | arg.Optional = false 47 | } 48 | } 49 | return nil 50 | } 51 | -------------------------------------------------------------------------------- /tos/tos_string.go: -------------------------------------------------------------------------------- 1 | package tos 2 | 3 | import "fmt" 4 | 5 | var ( 6 | _tosNameToValue map[string]ToS 7 | _tosValueToName = map[ToS]string{ 8 | CS3: "CS3", 9 | CS4: "CS4", 10 | CS5: "CS5", 11 | CS6: "CS6", 12 | CS7: "CS7", 13 | AF11: "AF11", 14 | AF12: "AF12", 15 | AF13: "AF13", 16 | AF21: "AF21", 17 | AF22: "AF22", 18 | AF23: "AF23", 19 | AF31: "AF31", 20 | AF32: "AF32", 21 | AF33: "AF33", 22 | AF41: "AF41", 23 | AF42: "AF42", 24 | AF43: "AF43", 25 | EF: "EF", 26 | Lowdelay: "Lowdelay", 27 | Throughput: "Throughput", 28 | Reliability: "Reliability", 29 | Lowcost: "Lowcost", 30 | } 31 | ) 32 | 33 | func init() { 34 | _tosNameToValue = make(map[string]ToS, len(_tosValueToName)) 35 | for tos, tosString := range _tosValueToName { 36 | _tosNameToValue[tosString] = tos 37 | } 38 | } 39 | 40 | // MarshalText implements TextMarshaler from encoding 41 | func (r ToS) MarshalText() ([]byte, error) { 42 | return []byte(_tosValueToName[r]), nil 43 | } 44 | 45 | // UnmarshalText implements TextUnMarshaler from encoding 46 | func (r *ToS) UnmarshalText(data []byte) error { 47 | if v, ok := _tosNameToValue[string(data)]; ok { 48 | *r = v 49 | return nil 50 | } 51 | 52 | return fmt.Errorf("invalid ToS %q", string(data)) 53 | } 54 | -------------------------------------------------------------------------------- /tos/tos_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package tos 22 | 23 | import ( 24 | "testing" 25 | 26 | "github.com/stretchr/testify/assert" 27 | "github.com/stretchr/testify/require" 28 | ) 29 | 30 | func TestMarshal(t *testing.T) { 31 | for tos, wantMarshalled := range _tosValueToName { 32 | marshalled, err := tos.MarshalText() 33 | require.NoError(t, err, "Failed to marshal %v", tos) 34 | assert.Equal(t, wantMarshalled, string(marshalled)) 35 | 36 | var got ToS 37 | err = got.UnmarshalText(marshalled) 38 | require.NoError(t, err, "Failed to unmarshal %v", string(marshalled)) 39 | assert.Equal(t, tos, got) 40 | } 41 | } 42 | 43 | func TestUnmarshalUnknown(t *testing.T) { 44 | var tos ToS 45 | err := tos.UnmarshalText([]byte("unknown")) 46 | require.Error(t, err, "Should fail to unmarshal unknown value") 47 | } 48 | -------------------------------------------------------------------------------- /trace/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | /* 22 | Package trace used to contain TChannel's distributed tracing functionality. 23 | It has since been replaced by integration with OpenTracing API. 24 | 25 | See http://opentracing.io 26 | 27 | This package is kept to alleviate problems with `glide update`, which tries 28 | to look for it during the dependencies upgrades. 29 | */ 30 | package trace 31 | -------------------------------------------------------------------------------- /trand/rand.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | // Package trand provides a thread-safe random number generator. 22 | package trand 23 | 24 | import ( 25 | "math/rand" 26 | "sync" 27 | "time" 28 | ) 29 | 30 | // lockedSource allows a random number generator to be used by multiple goroutines 31 | // concurrently. The code is very similar to math/rand.lockedSource, which is 32 | // unfortunately not exposed. 33 | type lockedSource struct { 34 | sync.Mutex 35 | 36 | src rand.Source 37 | } 38 | 39 | // New returns a rand.Rand that is threadsafe. 40 | func New(seed int64) *rand.Rand { 41 | return rand.New(&lockedSource{src: rand.NewSource(seed)}) 42 | } 43 | 44 | // NewSeeded returns a rand.Rand that's threadsafe and seeded with the current 45 | // time. 46 | func NewSeeded() *rand.Rand { 47 | return New(time.Now().UnixNano()) 48 | } 49 | 50 | func (r *lockedSource) Int63() (n int64) { 51 | r.Lock() 52 | n = r.src.Int63() 53 | r.Unlock() 54 | return 55 | } 56 | 57 | func (r *lockedSource) Seed(seed int64) { 58 | r.Lock() 59 | r.src.Seed(seed) 60 | r.Unlock() 61 | } 62 | -------------------------------------------------------------------------------- /typed/writer_test.go: -------------------------------------------------------------------------------- 1 | package typed 2 | 3 | import ( 4 | "errors" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/assert" 8 | "github.com/stretchr/testify/require" 9 | ) 10 | 11 | type dummyWriter struct { 12 | calls int 13 | bytesWritten []byte 14 | // retError is a map of call ids to error strings 15 | retError map[int]string 16 | } 17 | 18 | func (w *dummyWriter) Write(b []byte) (int, error) { 19 | defer func() { w.calls++ }() 20 | 21 | if w.retError[w.calls] != "" { 22 | return 0, errors.New(w.retError[w.calls]) 23 | } 24 | w.bytesWritten = append(w.bytesWritten, b...) 25 | return len(b), nil 26 | } 27 | 28 | func TestWriter(t *testing.T) { 29 | tests := []struct { 30 | msg string 31 | w *dummyWriter 32 | previousError error 33 | wantError string 34 | wantBytesWritten []byte 35 | }{ 36 | { 37 | msg: "successful write", 38 | w: &dummyWriter{ 39 | retError: map[int]string{}, 40 | }, 41 | wantBytesWritten: []byte{0, 1, 2, 0, 3, 4, 5, 6}, 42 | }, 43 | { 44 | msg: "return error due to previous error", 45 | previousError: errors.New("something went wrong previously"), 46 | w: &dummyWriter{}, 47 | wantError: "something went wrong previously", 48 | }, 49 | { 50 | msg: "error writing length", 51 | w: &dummyWriter{ 52 | retError: map[int]string{0: "something went wrong"}, 53 | }, 54 | wantError: "something went wrong", 55 | }, 56 | { 57 | msg: "error writing data", 58 | w: &dummyWriter{ 59 | retError: map[int]string{1: "something went wrong"}, 60 | }, 61 | wantError: "something went wrong", 62 | }, 63 | } 64 | 65 | for _, tt := range tests { 66 | t.Run(tt.msg, func(t *testing.T) { 67 | writes := func(w *Writer) { 68 | w.WriteUint16(1) 69 | w.WriteBytes([]byte{2}) 70 | w.WriteLen16Bytes([]byte{4, 5, 6}) 71 | } 72 | 73 | w := NewWriter(tt.w) 74 | w.err = tt.previousError 75 | writes(w) 76 | 77 | if tt.wantError != "" { 78 | require.EqualError(t, w.Err(), tt.wantError, "Got unexpected error") 79 | return 80 | } 81 | require.NoError(t, w.Err(), "Got unexpected error") 82 | assert.Equal(t, tt.wantBytesWritten, tt.w.bytesWritten) 83 | }) 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /verify_utils_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package tchannel_test 22 | 23 | import ( 24 | "testing" 25 | 26 | . "github.com/uber/tchannel-go" 27 | 28 | "github.com/uber/tchannel-go/testutils" 29 | ) 30 | 31 | // WithVerifiedServer runs the given test function with a server channel that is verified 32 | // at the end to make sure there are no leaks (e.g. no exchanges leaked). 33 | func WithVerifiedServer(t *testing.T, opts *testutils.ChannelOpts, f func(serverCh *Channel, hostPort string)) { 34 | testutils.WithTestServer(t, opts, func(t testing.TB, ts *testutils.TestServer) { 35 | f(ts.Server(), ts.HostPort()) 36 | }) 37 | } 38 | -------------------------------------------------------------------------------- /version.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Uber Technologies, Inc. 2 | 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package tchannel 22 | 23 | // VersionInfo identifies the version of the TChannel library. 24 | // Due to lack of proper package management, this version string will 25 | // be maintained manually. 26 | const VersionInfo = "1.34.6-dev" 27 | --------------------------------------------------------------------------------