github.com/hashicorp/go-plugin@v1.6.0/client_unix_test.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  //go:build !windows
     5  // +build !windows
     6  
     7  package plugin
     8  
     9  import (
    10  	"fmt"
    11  	"os"
    12  	"os/exec"
    13  	"os/user"
    14  	"path/filepath"
    15  	"runtime"
    16  	"syscall"
    17  	"testing"
    18  
    19  	"github.com/hashicorp/go-hclog"
    20  	"github.com/hashicorp/go-plugin/internal/cmdrunner"
    21  	"github.com/hashicorp/go-plugin/runner"
    22  )
    23  
    24  func TestSetGroup(t *testing.T) {
    25  	if runtime.GOOS == "windows" {
    26  		t.Skip("go-plugin doesn't support unix sockets on Windows")
    27  	}
    28  
    29  	group, err := user.LookupGroupId(fmt.Sprintf("%d", os.Getgid()))
    30  	if err != nil {
    31  		t.Fatal(err)
    32  	}
    33  	baseTempDir := t.TempDir()
    34  	baseTempDir, err = filepath.EvalSymlinks(baseTempDir)
    35  	if err != nil {
    36  		t.Fatal(err)
    37  	}
    38  	for name, tc := range map[string]struct {
    39  		group string
    40  	}{
    41  		"as integer": {fmt.Sprintf("%d", os.Getgid())},
    42  		"as name":    {group.Name},
    43  	} {
    44  		t.Run(name, func(t *testing.T) {
    45  			process := helperProcess("mock")
    46  			c := NewClient(&ClientConfig{
    47  				HandshakeConfig: testHandshake,
    48  				Plugins:         testPluginMap,
    49  				UnixSocketConfig: &UnixSocketConfig{
    50  					Group:   tc.group,
    51  					TempDir: baseTempDir,
    52  				},
    53  				RunnerFunc: func(l hclog.Logger, cmd *exec.Cmd, tmpDir string) (runner.Runner, error) {
    54  					// Run tests inside the RunnerFunc to ensure we don't race
    55  					// with the code that deletes tmpDir when the client fails
    56  					// to start properly.
    57  
    58  					// Test that it creates a directory with the proper owners and permissions.
    59  					if filepath.Dir(tmpDir) != baseTempDir {
    60  						t.Errorf("Expected base TempDir to be %s, but tmpDir was %s", baseTempDir, tmpDir)
    61  					}
    62  					info, err := os.Lstat(tmpDir)
    63  					if err != nil {
    64  						t.Fatal(err)
    65  					}
    66  					if info.Mode()&os.ModePerm != 0o770 {
    67  						t.Fatal(info.Mode())
    68  					}
    69  					stat, ok := info.Sys().(*syscall.Stat_t)
    70  					if !ok {
    71  						t.Fatal()
    72  					}
    73  					if stat.Gid != uint32(os.Getgid()) {
    74  						t.Fatalf("Expected %d, but got %d", os.Getgid(), stat.Gid)
    75  					}
    76  
    77  					// Check the correct environment variables were set to forward
    78  					// Unix socket config onto the plugin.
    79  					var foundUnixSocketDir, foundUnixSocketGroup bool
    80  					for _, env := range cmd.Env {
    81  						if env == fmt.Sprintf("%s=%s", EnvUnixSocketDir, tmpDir) {
    82  							foundUnixSocketDir = true
    83  						}
    84  						if env == fmt.Sprintf("%s=%s", EnvUnixSocketGroup, tc.group) {
    85  							foundUnixSocketGroup = true
    86  						}
    87  					}
    88  					if !foundUnixSocketDir {
    89  						t.Errorf("Did not find correct %s env in %v", EnvUnixSocketDir, cmd.Env)
    90  					}
    91  					if !foundUnixSocketGroup {
    92  						t.Errorf("Did not find correct %s env in %v", EnvUnixSocketGroup, cmd.Env)
    93  					}
    94  
    95  					process.Env = append(process.Env, cmd.Env...)
    96  					return cmdrunner.NewCmdRunner(l, process)
    97  				},
    98  			})
    99  			defer c.Kill()
   100  
   101  			_, err := c.Start()
   102  			if err != nil {
   103  				t.Fatalf("err should be nil, got %s", err)
   104  			}
   105  		})
   106  	}
   107  }