github.com/psiphon-labs/psiphon-tunnel-core@v2.0.28+incompatible/psiphon/common/utils_test.go (about) 1 /* 2 * Copyright (c) 2014, 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 "bytes" 24 "context" 25 "encoding/json" 26 "net/url" 27 "reflect" 28 "strings" 29 "testing" 30 "time" 31 ) 32 33 func TestGetStringSlice(t *testing.T) { 34 35 originalSlice := []string{"a", "b", "c"} 36 37 j, err := json.Marshal(originalSlice) 38 if err != nil { 39 t.Errorf("json.Marshal failed: %s", err) 40 } 41 42 var value interface{} 43 44 err = json.Unmarshal(j, &value) 45 if err != nil { 46 t.Errorf("json.Unmarshal failed: %s", err) 47 } 48 49 newSlice, ok := GetStringSlice(value) 50 if !ok { 51 t.Errorf("GetStringSlice failed") 52 } 53 54 if !reflect.DeepEqual(originalSlice, newSlice) { 55 t.Errorf("unexpected GetStringSlice output") 56 } 57 } 58 59 func TestCompress(t *testing.T) { 60 61 originalData := []byte("test data") 62 63 compressedData := Compress(originalData) 64 65 decompressedData, err := Decompress(compressedData) 66 if err != nil { 67 t.Errorf("Uncompress failed: %s", err) 68 } 69 70 if !bytes.Equal(originalData, decompressedData) { 71 t.Error("decompressed data doesn't match original data") 72 } 73 } 74 75 func TestFormatByteCount(t *testing.T) { 76 77 testCases := []struct { 78 n uint64 79 expectedOutput string 80 }{ 81 {500, "500B"}, 82 {1024, "1.0K"}, 83 {10000, "9.8K"}, 84 {1024*1024 + 1, "1.0M"}, 85 {100*1024*1024 + 99999, "100.1M"}, 86 } 87 88 for _, testCase := range testCases { 89 t.Run(testCase.expectedOutput, func(t *testing.T) { 90 output := FormatByteCount(testCase.n) 91 if output != testCase.expectedOutput { 92 t.Errorf("unexpected output: %s", output) 93 } 94 }) 95 } 96 } 97 98 func TestSafeParseURL(t *testing.T) { 99 100 invalidURL := "https://invalid url" 101 102 _, err := url.Parse(invalidURL) 103 104 if err == nil { 105 t.Error("unexpected parse success") 106 } 107 108 if strings.Index(err.Error(), invalidURL) == -1 { 109 t.Error("URL not in error string") 110 } 111 112 _, err = SafeParseURL(invalidURL) 113 114 if err == nil { 115 t.Error("unexpected parse success") 116 } 117 118 if strings.Index(err.Error(), invalidURL) != -1 { 119 t.Error("URL in error string") 120 } 121 } 122 123 func TestSafeParseRequestURI(t *testing.T) { 124 125 invalidURL := "https://invalid url" 126 127 _, err := url.ParseRequestURI(invalidURL) 128 129 if err == nil { 130 t.Error("unexpected parse success") 131 } 132 133 if strings.Index(err.Error(), invalidURL) == -1 { 134 t.Error("URL not in error string") 135 } 136 137 _, err = SafeParseRequestURI(invalidURL) 138 139 if err == nil { 140 t.Error("unexpected parse success") 141 } 142 143 if strings.Index(err.Error(), invalidURL) != -1 { 144 t.Error("URL in error string") 145 } 146 } 147 148 func TestSleepWithContext(t *testing.T) { 149 150 start := time.Now() 151 SleepWithContext(context.Background(), 100*time.Millisecond) 152 duration := time.Since(start) 153 // Allows for 100-109ms actual elapsed time. 154 if duration/time.Millisecond/10 != 10 { 155 t.Errorf("unexpected duration: %v", duration) 156 } 157 158 start = time.Now() 159 ctx, cancelFunc := context.WithTimeout(context.Background(), 100*time.Millisecond) 160 defer cancelFunc() 161 SleepWithContext(ctx, 50*time.Millisecond) 162 duration = time.Since(start) 163 if duration/time.Millisecond/10 != 5 { 164 t.Errorf("unexpected duration: %v", duration) 165 } 166 }