github.com/psiphon-labs/psiphon-tunnel-core@v2.0.28+incompatible/psiphon/common/activity_test.go (about)

     1  /*
     2   * Copyright (c) 2020, Psiphon Inc.
     3   * All rights reserved.
     4   *
     5   * This program is free software: you can redistribute it and/or modify
     6   * it under the terms of the GNU General Public License as published by
     7   * the Free Software Foundation, either version 3 of the License, or
     8   * (at your option) any later version.
     9   *
    10   * This program is distributed in the hope that it will be useful,
    11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13   * GNU General Public License for more details.
    14   *
    15   * You should have received a copy of the GNU General Public License
    16   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17   *
    18   */
    19  
    20  package common
    21  
    22  import (
    23  	"testing"
    24  	"testing/iotest"
    25  	"time"
    26  
    27  	"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/monotime"
    28  )
    29  
    30  func TestActivityMonitoredConn(t *testing.T) {
    31  	buffer := make([]byte, 1024)
    32  
    33  	conn, err := NewActivityMonitoredConn(
    34  		&dummyConn{},
    35  		200*time.Millisecond,
    36  		true,
    37  		nil)
    38  	if err != nil {
    39  		t.Fatalf("NewActivityMonitoredConn failed")
    40  	}
    41  
    42  	realStartTime := time.Now().UTC()
    43  
    44  	monotonicStartTime := monotime.Now()
    45  
    46  	time.Sleep(100 * time.Millisecond)
    47  
    48  	_, err = conn.Read(buffer)
    49  	if err != nil {
    50  		t.Fatalf("read before initial timeout failed")
    51  	}
    52  
    53  	time.Sleep(100 * time.Millisecond)
    54  
    55  	_, err = conn.Read(buffer)
    56  	if err != nil {
    57  		t.Fatalf("previous read failed to extend timeout")
    58  	}
    59  
    60  	time.Sleep(100 * time.Millisecond)
    61  
    62  	_, err = conn.Write(buffer)
    63  	if err != nil {
    64  		t.Fatalf("previous read failed to extend timeout")
    65  	}
    66  
    67  	time.Sleep(100 * time.Millisecond)
    68  
    69  	_, err = conn.Read(buffer)
    70  	if err != nil {
    71  		t.Fatalf("previous write failed to extend timeout")
    72  	}
    73  
    74  	lastSuccessfulReadTime := monotime.Now()
    75  
    76  	time.Sleep(100 * time.Millisecond)
    77  
    78  	_, err = conn.Write(buffer)
    79  	if err != nil {
    80  		t.Fatalf("previous read failed to extend timeout")
    81  	}
    82  
    83  	time.Sleep(300 * time.Millisecond)
    84  
    85  	_, err = conn.Read(buffer)
    86  	if err != iotest.ErrTimeout {
    87  		t.Fatalf("failed to timeout")
    88  	}
    89  
    90  	if realStartTime.Round(time.Millisecond) != conn.GetStartTime().Round(time.Millisecond) {
    91  		t.Fatalf("unexpected GetStartTime")
    92  	}
    93  
    94  	diff := lastSuccessfulReadTime.Sub(monotonicStartTime).Nanoseconds() - conn.GetActiveDuration().Nanoseconds()
    95  	if diff < 0 {
    96  		diff = -diff
    97  	}
    98  	if diff > (1 * time.Millisecond).Nanoseconds() {
    99  		t.Fatalf("unexpected GetActiveDuration")
   100  	}
   101  }
   102  
   103  func TestActivityMonitoredLRUConns(t *testing.T) {
   104  
   105  	lruConns := NewLRUConns()
   106  
   107  	dummy1 := &dummyConn{}
   108  	conn1, err := NewActivityMonitoredConn(dummy1, 0, true, lruConns.Add(dummy1))
   109  	if err != nil {
   110  		t.Fatalf("NewActivityMonitoredConn failed")
   111  	}
   112  
   113  	dummy2 := &dummyConn{}
   114  	conn2, err := NewActivityMonitoredConn(dummy2, 0, true, lruConns.Add(dummy2))
   115  	if err != nil {
   116  		t.Fatalf("NewActivityMonitoredConn failed")
   117  	}
   118  
   119  	dummy3 := &dummyConn{}
   120  	conn3, err := NewActivityMonitoredConn(dummy3, 0, true, lruConns.Add(dummy3))
   121  	if err != nil {
   122  		t.Fatalf("NewActivityMonitoredConn failed")
   123  	}
   124  
   125  	buffer := make([]byte, 1024)
   126  
   127  	conn1.Read(buffer)
   128  	conn2.Read(buffer)
   129  	conn3.Read(buffer)
   130  
   131  	conn3.Write(buffer)
   132  	conn2.Write(buffer)
   133  	conn1.Write(buffer)
   134  
   135  	if dummy1.IsClosed() || dummy2.IsClosed() || dummy3.IsClosed() {
   136  		t.Fatalf("unexpected IsClosed state")
   137  	}
   138  
   139  	lruConns.CloseOldest()
   140  
   141  	if dummy1.IsClosed() || dummy2.IsClosed() || !dummy3.IsClosed() {
   142  		t.Fatalf("unexpected IsClosed state")
   143  	}
   144  
   145  	lruConns.CloseOldest()
   146  
   147  	if dummy1.IsClosed() || !dummy2.IsClosed() || !dummy3.IsClosed() {
   148  		t.Fatalf("unexpected IsClosed state")
   149  	}
   150  
   151  	lruConns.CloseOldest()
   152  
   153  	if !dummy1.IsClosed() || !dummy2.IsClosed() || !dummy3.IsClosed() {
   154  		t.Fatalf("unexpected IsClosed state")
   155  	}
   156  }