summaryrefslogtreecommitdiff
path: root/tunnels/tunnels_test.go
diff options
context:
space:
mode:
authorLukasz Wojciechowski <l.wojciechow@partner.samsung.com>2017-10-31 09:59:38 +0100
committerLukasz Wojciechowski <l.wojciechow@partner.samsung.com>2018-04-27 17:34:20 +0200
commit38ef549139849d62ffe88af54af14ab7d456ebf8 (patch)
treeb5dbd56c116f5ab8cd9c83cc1f1b703dbbef88fc /tunnels/tunnels_test.go
parent9eec2c2c3f17322be8d9eab30ff174f9173a2120 (diff)
downloadboruta-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.go120
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())
+ })
+})