@@ -20,7 +20,7 @@ import (
2020var (
2121 // Shared variables and sync.Once instances to ensure one-time execution
2222 getTokenOnce sync.Once
23- e2eToken string
23+ token string
2424
2525 buildOnce sync.Once
2626 buildError error
@@ -29,12 +29,12 @@ var (
2929// getE2EToken ensures the environment variable is checked only once and returns the token
3030func getE2EToken (t * testing.T ) string {
3131 getTokenOnce .Do (func () {
32- e2eToken = os .Getenv ("GITHUB_MCP_SERVER_E2E_TOKEN" )
33- if e2eToken == "" {
32+ token = os .Getenv ("GITHUB_MCP_SERVER_E2E_TOKEN" )
33+ if token == "" {
3434 t .Fatalf ("GITHUB_MCP_SERVER_E2E_TOKEN environment variable is not set" )
3535 }
3636 })
37- return e2eToken
37+ return token
3838}
3939
4040// ensureDockerImageBuilt makes sure the Docker image is built only once across all tests
@@ -54,25 +54,79 @@ func ensureDockerImageBuilt(t *testing.T) {
5454 require .NoError (t , buildError , "expected to build Docker image successfully" )
5555}
5656
57- func TestE2E (t * testing.T ) {
57+ // ClientOpts holds configuration options for the MCP client setup
58+ type ClientOpts struct {
59+ // Environment variables to set before starting the client
60+ EnvVars map [string ]string
61+ // Whether to initialize the client after creation
62+ ShouldInitialize bool
63+ }
64+
65+ // ClientOption defines a function type for configuring ClientOpts
66+ type ClientOption func (* ClientOpts )
67+
68+ // WithEnvVars returns an option that adds environment variables to the client options
69+ func WithEnvVars (envVars map [string ]string ) ClientOption {
70+ return func (opts * ClientOpts ) {
71+ opts .EnvVars = envVars
72+ }
73+ }
74+
75+ // WithInitialize returns an option that configures the client to be initialized
76+ func WithInitialize () ClientOption {
77+ return func (opts * ClientOpts ) {
78+ opts .ShouldInitialize = true
79+ }
80+ }
81+
82+ // setupMCPClient sets up the test environment and returns an initialized MCP client
83+ // It handles token retrieval, Docker image building, and applying the provided options
84+ func setupMCPClient (t * testing.T , options ... ClientOption ) * mcpClient.Client {
85+ // Get token and ensure Docker image is built
5886 token := getE2EToken (t )
5987 ensureDockerImageBuilt (t )
6088
61- t .Setenv ("GITHUB_PERSONAL_ACCESS_TOKEN" , token ) // The MCP Client merges the existing environment.
89+ // Create and configure options
90+ opts := & ClientOpts {
91+ EnvVars : make (map [string ]string ),
92+ }
93+
94+ // Apply all options to configure the opts struct
95+ for _ , option := range options {
96+ option (opts )
97+ }
98+
99+ // Set the GitHub token and other environment variables
100+ t .Setenv ("GITHUB_PERSONAL_ACCESS_TOKEN" , token )
101+ for key , value := range opts .EnvVars {
102+ t .Setenv (key , value )
103+ }
104+
105+ // Prepare Docker arguments
62106 args := []string {
63107 "docker" ,
64108 "run" ,
65109 "-i" ,
66110 "--rm" ,
67111 "-e" ,
68112 "GITHUB_PERSONAL_ACCESS_TOKEN" ,
69- "github/e2e-github-mcp-server" ,
70113 }
114+
115+ // Add all environment variables to the Docker arguments
116+ for key := range opts .EnvVars {
117+ args = append (args , "-e" , key )
118+ }
119+
120+ // Add the image name
121+ args = append (args , "github/e2e-github-mcp-server" )
122+
123+ // Create the client
71124 t .Log ("Starting Stdio MCP client..." )
72125 client , err := mcpClient .NewStdioMCPClient (args [0 ], []string {}, args [1 :]... )
73126 require .NoError (t , err , "expected to create client successfully" )
74127
75- t .Run ("Initialize" , func (t * testing.T ) {
128+ // Initialize the client if configured to do so
129+ if opts .ShouldInitialize {
76130 ctx , cancel := context .WithTimeout (context .Background (), 5 * time .Second )
77131 defer cancel ()
78132
@@ -84,10 +138,16 @@ func TestE2E(t *testing.T) {
84138 }
85139
86140 result , err := client .Initialize (ctx , request )
87- require .NoError (t , err , "expected to initialize successfully" )
141+ require .NoError (t , err , "failed to initialize client" )
142+ require .Equal (t , "github-mcp-server" , result .ServerInfo .Name , "unexpected server name" )
143+ }
88144
89- require .Equal (t , "github-mcp-server" , result .ServerInfo .Name )
90- })
145+ return client
146+ }
147+
148+ func TestE2E (t * testing.T ) {
149+ // Setup the MCP client with initialization
150+ client := setupMCPClient (t , WithInitialize ())
91151
92152 t .Run ("CallTool get_me" , func (t * testing.T ) {
93153 ctx , cancel := context .WithTimeout (context .Background (), 5 * time .Second )
@@ -114,7 +174,7 @@ func TestE2E(t *testing.T) {
114174
115175 // Then the login in the response should match the login obtained via the same
116176 // token using the GitHub API.
117- client := github .NewClient (nil ).WithAuthToken (token )
177+ client := github .NewClient (nil ).WithAuthToken (getE2EToken ( t ) )
118178 user , _ , err := client .Users .Get (context .Background (), "" )
119179 require .NoError (t , err , "expected to get user successfully" )
120180 require .Equal (t , trimmedContent .Login , * user .Login , "expected login to match" )
0 commit comments