github.com/psiphon-labs/psiphon-tunnel-core@v2.0.28+incompatible/psiphon/tactics_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 psiphon 21 22 import ( 23 "context" 24 "encoding/json" 25 "io/ioutil" 26 "net" 27 "os" 28 "sync/atomic" 29 "testing" 30 "time" 31 32 "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/errors" 33 ) 34 35 func TestStandAloneGetTactics(t *testing.T) { 36 37 testDataDirName, err := ioutil.TempDir("", "psiphon-tactics-test") 38 if err != nil { 39 t.Fatalf("TempDir failed: %s\n", err) 40 } 41 defer os.RemoveAll(testDataDirName) 42 43 configJSON, err := ioutil.ReadFile("controller_test.config") 44 if err != nil { 45 // Skip, don't fail, if config file is not present 46 t.Skipf("error loading configuration file: %s", err) 47 } 48 49 var modifyConfig map[string]interface{} 50 json.Unmarshal(configJSON, &modifyConfig) 51 52 modifyConfig["DataRootDirectory"] = testDataDirName 53 54 configJSON, _ = json.Marshal(modifyConfig) 55 56 config, err := LoadConfig(configJSON) 57 if err != nil { 58 t.Fatalf("error processing configuration file: %s", err) 59 } 60 61 if config.ClientPlatform == "" { 62 config.ClientPlatform = testClientPlatform 63 } 64 65 err = config.Commit(false) 66 if err != nil { 67 t.Fatalf("error committing configuration file: %s", err) 68 } 69 70 resolver := NewResolver(config, true) 71 defer resolver.Stop() 72 config.SetResolver(resolver) 73 74 gotTactics := int32(0) 75 76 SetNoticeWriter(NewNoticeReceiver( 77 func(notice []byte) { 78 noticeType, _, err := GetNotice(notice) 79 if err != nil { 80 return 81 } 82 switch noticeType { 83 case "RequestedTactics": 84 atomic.StoreInt32(&gotTactics, 1) 85 } 86 })) 87 88 ctx, cancelFunc := context.WithTimeout(context.Background(), 30*time.Second) 89 defer cancelFunc() 90 91 err = OpenDataStore(config) 92 if err != nil { 93 t.Fatalf("error committing initializing datastore: %s", err) 94 } 95 96 untunneledDialConfig := &DialConfig{ 97 ResolveIP: func(ctx context.Context, hostname string) ([]net.IP, error) { 98 IPs, err := UntunneledResolveIP( 99 ctx, config, resolver, hostname) 100 if err != nil { 101 return nil, errors.Trace(err) 102 } 103 return IPs, nil 104 }, 105 UpstreamProxyURL: config.UpstreamProxyURL, 106 } 107 108 err = FetchCommonRemoteServerList(ctx, config, 0, nil, untunneledDialConfig) 109 if err != nil { 110 t.Fatalf("error fetching remote server list: %s", err) 111 } 112 113 // Close the datastore to exercise the OpenDatastore/CloseDatastore 114 // operations in GetTactics. 115 CloseDataStore() 116 117 GetTactics(ctx, config) 118 119 if atomic.LoadInt32(&gotTactics) != 1 { 120 t.Fatalf("failed to get tactics") 121 } 122 }