diff options
author | Lukasz Wojciechowski <l.wojciechow@partner.samsung.com> | 2017-10-31 09:59:38 +0100 |
---|---|---|
committer | Lukasz Wojciechowski <l.wojciechow@partner.samsung.com> | 2018-04-27 17:34:20 +0200 |
commit | 38ef549139849d62ffe88af54af14ab7d456ebf8 (patch) | |
tree | b5dbd56c116f5ab8cd9c83cc1f1b703dbbef88fc /tunnels/tunnels_test.go | |
parent | 9eec2c2c3f17322be8d9eab30ff174f9173a2120 (diff) | |
download | boruta-38ef549139849d62ffe88af54af14ab7d456ebf8.tar.gz boruta-38ef549139849d62ffe88af54af14ab7d456ebf8.tar.bz2 boruta-38ef549139849d62ffe88af54af14ab7d456ebf8.zip |
Move tunnels from workers to separate package
Tunnels package provides implementation of simple data forwarding
tunnels between IP addresses pairs.
The implementation has been moved from workers package and adjusted
to newly defined Tunneler interface. The interface defines basic
operations on tunnels (creation, getting address, closing).
It provides additional layer of abstraction allowing mockuping tests
of parts of the code using tunnels.
The mock implementation of interface is provided in matcher package.
It is generated using mockgen command:
mockgen -package matcher \
-destination=matcher/tunneler_mock_test.go \
-write_package_comment=false \
git.tizen.org/tools/boruta/tunnels Tunneler
Change-Id: Ida42f0134f0c365c8f1ffe772b859a0218c301ed
Signed-off-by: Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
Signed-off-by: Maciej Wereski <m.wereski@partner.samsung.com>
Diffstat (limited to 'tunnels/tunnels_test.go')
-rw-r--r-- | tunnels/tunnels_test.go | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/tunnels/tunnels_test.go b/tunnels/tunnels_test.go new file mode 100644 index 0000000..99af08f --- /dev/null +++ b/tunnels/tunnels_test.go @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2017-2018 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ +package tunnels + +import ( + "io" + "net" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +var _ = Describe("Tunnels", func() { + invalidIP := net.IPv4(255, 8, 8, 8) + + listen := func(done chan struct{}, in, out string) *net.TCPAddr { + addr := new(net.TCPAddr) + ln, err := net.ListenTCP("tcp", addr) + go func() { + defer close(done) + defer GinkgoRecover() + // Accept a single connection + defer ln.Close() + conn, err := ln.Accept() + Expect(err).ToNot(HaveOccurred()) + defer conn.Close() + if in != "" { + buf := make([]byte, len(in)) + _, err := io.ReadFull(conn, buf) + Expect(err).ToNot(HaveOccurred()) + Expect(string(buf)).To(Equal(in)) + } + if out != "" { + _, err := io.WriteString(conn, out) + Expect(err).ToNot(HaveOccurred()) + } + }() + Expect(err).ToNot(HaveOccurred()) + return ln.Addr().(*net.TCPAddr) + } + + var t *Tunnel + + BeforeEach(func() { + t = new(Tunnel) + Expect(t).NotTo(BeNil()) + }) + + It("should make a connection", func() { + done := make(chan struct{}) + lAddr := listen(done, "", "") + err := t.create(nil, nil, lAddr.Port) + Expect(err).ToNot(HaveOccurred()) + + conn, err := net.DialTCP("tcp", nil, lAddr) + Expect(err).ToNot(HaveOccurred()) + + defer conn.Close() + Eventually(done).Should(BeClosed()) + Expect(t.Close()).To(Succeed()) + }) + + It("should pass data through", func() { + done := make(chan struct{}) + testIn := "input test string" + testOut := "output test string" + lAddr := listen(done, testIn, testOut) + err := t.create(nil, nil, lAddr.Port) + Expect(err).ToNot(HaveOccurred()) + conn, err := net.DialTCP("tcp", nil, t.Addr().(*net.TCPAddr)) + Expect(err).ToNot(HaveOccurred()) + defer conn.Close() + + _, err = io.WriteString(conn, testIn) + Expect(err).ToNot(HaveOccurred()) + buf := make([]byte, len(testOut)) + _, err = io.ReadFull(conn, buf) + Expect(err).ToNot(HaveOccurred()) + Expect(string(buf)).To(Equal(testOut)) + + Eventually(done).Should(BeClosed()) + Expect(t.Close()).To(Succeed()) + }) + + It("should fail to listen on invalid address", func() { + err := t.Create(invalidIP, nil) + Expect(err).To(HaveOccurred()) + }) + + It("should fail to connect to invalid address", func() { + err := t.create(nil, nil, 0) + Expect(err).ToNot(HaveOccurred()) + + conn, err := net.DialTCP("tcp", nil, t.Addr().(*net.TCPAddr)) + Expect(err).ToNot(HaveOccurred()) + defer conn.Close() + + // There is no good way to check for closed connection + // so we wait for some error to occur: + // write tcp [::1]:36454->[::1]:42173: write: broken pipe + // It usually takes 2 attempts. + Eventually(func() error { + _, err = io.WriteString(conn, "test") + return err + }).Should(HaveOccurred()) + }) +}) |