github.com/argoproj/argo-cd@v1.8.7/server/server_norace_test.go (about) 1 // +build !race 2 3 package server 4 5 import ( 6 "context" 7 "fmt" 8 "io/ioutil" 9 "net/http" 10 "strings" 11 "testing" 12 "time" 13 14 "github.com/stretchr/testify/assert" 15 16 "github.com/argoproj/argo-cd/common" 17 "github.com/argoproj/argo-cd/pkg/apiclient" 18 "github.com/argoproj/argo-cd/test" 19 20 applicationpkg "github.com/argoproj/argo-cd/pkg/apiclient/application" 21 ) 22 23 func TestUserAgent(t *testing.T) { 24 25 // !race: 26 // A data race in go-client's `shared_informer.go`, between `sharedProcessor.run(...)` and itself. Based on 27 // the data race, it APPEARS to be intentional, but in any case it's nothing we are doing in Argo CD 28 // that is causing this issue. 29 30 s := fakeServer() 31 cancelInformer := test.StartInformer(s.projInformer) 32 defer cancelInformer() 33 port, err := test.GetFreePort() 34 assert.NoError(t, err) 35 metricsPort, err := test.GetFreePort() 36 assert.NoError(t, err) 37 ctx, cancel := context.WithCancel(context.Background()) 38 defer cancel() 39 go s.Run(ctx, port, metricsPort) 40 defer func() { time.Sleep(3 * time.Second) }() 41 42 err = test.WaitForPortListen(fmt.Sprintf("127.0.0.1:%d", port), 10*time.Second) 43 assert.NoError(t, err) 44 45 type testData struct { 46 userAgent string 47 errorMsg string 48 } 49 currentVersionBytes, err := ioutil.ReadFile("../VERSION") 50 assert.NoError(t, err) 51 currentVersion := strings.TrimSpace(string(currentVersionBytes)) 52 var tests = []testData{ 53 { 54 // Reject out-of-date user-agent 55 userAgent: fmt.Sprintf("%s/0.10.0", common.ArgoCDUserAgentName), 56 errorMsg: "unsatisfied client version constraint", 57 }, 58 { 59 // Accept up-to-date user-agent 60 userAgent: fmt.Sprintf("%s/%s", common.ArgoCDUserAgentName, currentVersion), 61 }, 62 { 63 // Accept up-to-date pre-release user-agent 64 userAgent: fmt.Sprintf("%s/%s-rc1", common.ArgoCDUserAgentName, currentVersion), 65 }, 66 { 67 // Reject legacy client 68 // NOTE: after we update the grpc-go client past 1.15.0, this test will break and should be deleted 69 userAgent: " ", // need a space here since the apiclient will set the default user-agent if empty 70 errorMsg: "unsatisfied client version constraint", 71 }, 72 { 73 // Permit custom clients 74 userAgent: "foo/1.2.3", 75 }, 76 } 77 78 for _, test := range tests { 79 opts := apiclient.ClientOptions{ 80 ServerAddr: fmt.Sprintf("localhost:%d", port), 81 PlainText: true, 82 UserAgent: test.userAgent, 83 } 84 clnt, err := apiclient.NewClient(&opts) 85 assert.NoError(t, err) 86 conn, appClnt := clnt.NewApplicationClientOrDie() 87 _, err = appClnt.List(ctx, &applicationpkg.ApplicationQuery{}) 88 if test.errorMsg != "" { 89 assert.Error(t, err) 90 assert.Regexp(t, test.errorMsg, err.Error()) 91 } else { 92 assert.NoError(t, err) 93 } 94 _ = conn.Close() 95 } 96 } 97 98 func Test_StaticHeaders(t *testing.T) { 99 100 // !race: 101 // Same as TestUserAgent 102 103 // Test default policy "sameorigin" 104 { 105 s := fakeServer() 106 cancelInformer := test.StartInformer(s.projInformer) 107 defer cancelInformer() 108 port, err := test.GetFreePort() 109 assert.NoError(t, err) 110 metricsPort, err := test.GetFreePort() 111 assert.NoError(t, err) 112 ctx, cancel := context.WithCancel(context.Background()) 113 defer cancel() 114 go s.Run(ctx, port, metricsPort) 115 defer func() { time.Sleep(3 * time.Second) }() 116 117 err = test.WaitForPortListen(fmt.Sprintf("127.0.0.1:%d", port), 10*time.Second) 118 assert.NoError(t, err) 119 120 // Allow server startup 121 time.Sleep(1 * time.Second) 122 123 client := http.Client{} 124 url := fmt.Sprintf("http://127.0.0.1:%d/test.html", port) 125 req, err := http.NewRequest("GET", url, nil) 126 assert.NoError(t, err) 127 resp, err := client.Do(req) 128 assert.NoError(t, err) 129 assert.Equal(t, "sameorigin", resp.Header.Get("X-Frame-Options")) 130 } 131 132 // Test custom policy 133 { 134 s := fakeServer() 135 s.XFrameOptions = "deny" 136 cancelInformer := test.StartInformer(s.projInformer) 137 defer cancelInformer() 138 port, err := test.GetFreePort() 139 assert.NoError(t, err) 140 metricsPort, err := test.GetFreePort() 141 assert.NoError(t, err) 142 ctx, cancel := context.WithCancel(context.Background()) 143 defer cancel() 144 go s.Run(ctx, port, metricsPort) 145 defer func() { time.Sleep(3 * time.Second) }() 146 147 err = test.WaitForPortListen(fmt.Sprintf("127.0.0.1:%d", port), 10*time.Second) 148 assert.NoError(t, err) 149 150 // Allow server startup 151 time.Sleep(1 * time.Second) 152 153 client := http.Client{} 154 url := fmt.Sprintf("http://127.0.0.1:%d/test.html", port) 155 req, err := http.NewRequest("GET", url, nil) 156 assert.NoError(t, err) 157 resp, err := client.Do(req) 158 assert.NoError(t, err) 159 assert.Equal(t, "deny", resp.Header.Get("X-Frame-Options")) 160 } 161 162 // Test disabled 163 { 164 s := fakeServer() 165 s.XFrameOptions = "" 166 cancelInformer := test.StartInformer(s.projInformer) 167 defer cancelInformer() 168 port, err := test.GetFreePort() 169 assert.NoError(t, err) 170 metricsPort, err := test.GetFreePort() 171 assert.NoError(t, err) 172 ctx, cancel := context.WithCancel(context.Background()) 173 defer cancel() 174 go s.Run(ctx, port, metricsPort) 175 defer func() { time.Sleep(3 * time.Second) }() 176 177 err = test.WaitForPortListen(fmt.Sprintf("127.0.0.1:%d", port), 10*time.Second) 178 assert.NoError(t, err) 179 180 // Allow server startup 181 time.Sleep(1 * time.Second) 182 183 client := http.Client{} 184 url := fmt.Sprintf("http://127.0.0.1:%d/test.html", port) 185 req, err := http.NewRequest("GET", url, nil) 186 assert.NoError(t, err) 187 resp, err := client.Do(req) 188 assert.NoError(t, err) 189 assert.Empty(t, resp.Header.Get("X-Frame-Options")) 190 } 191 }