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  }