diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7223e30c3a..3cd8f92954 100755 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -55,6 +55,11 @@ jobs: # === OS Specific Steps === steps: + - # === Disable Windows Defender as it slows things down significantly === + name: Disabling Windows Defender + if: runner.os == 'Windows' + shell: powershell + run: Set-MpPreference -DisableRealtimeMonitoring $true - # === Checkout Code === name: Checkout code @@ -313,14 +318,13 @@ jobs: echo "Running integration tests with tags: $TEST_SUITE_TAGS (empty means every test not specifically tagged)" export TEST_SUITE_TAGS="$TEST_SUITE_TAGS" - TIMEOUT=15m + TIMEOUT=30m if [[ "$TEST_SUITE_TAGS" == "all" ]]; then TIMEOUT=60m fi SHELL='' go test -timeout $TIMEOUT -v `go list ./... | grep "integration"` -json 2>&1 | gotestfmt -hide empty-packages continue-on-error: ${{ github.event_name == 'schedule' }} env: - ACTIVESTATE_VERBOSE: true INTEGRATION_TEST_USERNAME: ${{ secrets.INTEGRATION_TEST_USERNAME }} INTEGRATION_TEST_PASSWORD: ${{ secrets.INTEGRATION_TEST_PASSWORD }} INTEGRATION_TEST_TOKEN: ${{ secrets.INTEGRATION_TEST_TOKEN }} diff --git a/.golangci.yaml b/.golangci.yaml index 548915910f..8bd835bdbd 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -9,7 +9,7 @@ linters-settings: - (*github.com/ActiveState/termtest.ConsoleProcess).ExpectExitCode - (*github.com/ActiveState/termtest.ConsoleProcess).ExpectNotExitCode - (*github.com/ActiveState/termtest.ConsoleProcess).ExpectRe - - (*github.com/ActiveState/termtest.ConsoleProcess).ExpectLongString + - (*github.com/ActiveState/termtest.ConsoleProcess).Expect - (*github.com/ActiveState/termtest.ConsoleProcess).WaitForInput # When issues occur with linting us the snippet below to help with debugging @@ -23,4 +23,4 @@ linters-settings: # - ineffassign # - staticcheck # - typecheck -# - unused \ No newline at end of file +# - unused diff --git a/cmd/state-installer/test/integration/installer_int_test.go b/cmd/state-installer/test/integration/installer_int_test.go index 2616c27e12..e65da195e2 100644 --- a/cmd/state-installer/test/integration/installer_int_test.go +++ b/cmd/state-installer/test/integration/installer_int_test.go @@ -46,9 +46,9 @@ func (suite *InstallerIntegrationTestSuite) TestInstallFromLocalSource() { // Run installer with source-path flag (ie. install from this local path) cp := ts.SpawnCmdWithOpts( suite.installerExe, - e2e.WithArgs(installationDir(ts)), - e2e.AppendEnv(constants.DisableUpdates+"=false"), - e2e.AppendEnv(fmt.Sprintf("%s=%s", constants.OverwriteDefaultSystemPathEnvVarName, dir)), + e2e.OptArgs(installationDir(ts)), + e2e.OptAppendEnv(constants.DisableUpdates+"=false"), + e2e.OptAppendEnv(fmt.Sprintf("%s=%s", constants.OverwriteDefaultSystemPathEnvVarName, dir)), ) // Assert output @@ -58,20 +58,20 @@ func (suite *InstallerIntegrationTestSuite) TestInstallFromLocalSource() { if runtime.GOOS == "darwin" && condition.OnCI() { cp.Expect("You are running bash on macOS") } - suite.NotContains(cp.TrimmedSnapshot(), "Downloading State Tool") - cp.WaitForInput() + suite.NotContains(cp.Output(), "Downloading State Tool") + cp.ExpectInput() cp.SendLine("exit") cp.ExpectExitCode(0) // Ensure installing overtop doesn't result in errors cp = ts.SpawnCmdWithOpts( suite.installerExe, - e2e.WithArgs(installationDir(ts)), - e2e.AppendEnv(constants.DisableUpdates+"=false"), - e2e.AppendEnv(fmt.Sprintf("%s=%s", constants.OverwriteDefaultSystemPathEnvVarName, dir)), + e2e.OptArgs(installationDir(ts)), + e2e.OptAppendEnv(constants.DisableUpdates+"=false"), + e2e.OptAppendEnv(fmt.Sprintf("%s=%s", constants.OverwriteDefaultSystemPathEnvVarName, dir)), ) cp.Expect("successfully installed") - cp.WaitForInput() + cp.ExpectInput() cp.SendLine("exit") cp.ExpectExitCode(0) @@ -80,9 +80,9 @@ func (suite *InstallerIntegrationTestSuite) TestInstallFromLocalSource() { suite.Require().NoError(fileutils.WriteFile(filepath.Join(installationDir(ts), installation.InstallDirMarker), []byte{})) cp = ts.SpawnCmdWithOpts( suite.installerExe, - e2e.WithArgs(installationDir(ts)), - e2e.AppendEnv(constants.DisableUpdates+"=false"), - e2e.AppendEnv(fmt.Sprintf("%s=%s", constants.OverwriteDefaultSystemPathEnvVarName, dir)), + e2e.OptArgs(installationDir(ts)), + e2e.OptAppendEnv(constants.DisableUpdates+"=false"), + e2e.OptAppendEnv(fmt.Sprintf("%s=%s", constants.OverwriteDefaultSystemPathEnvVarName, dir)), ) cp.Expect("successfully installed") @@ -99,21 +99,21 @@ func (suite *InstallerIntegrationTestSuite) TestInstallFromLocalSource() { suite.NoError(err) // Verify that launched subshell has State tool on PATH - cp.WaitForInput() + cp.ExpectInput() cp.SendLine("state --version") cp.Expect("Version") - cp.WaitForInput() + cp.ExpectInput() if runtime.GOOS == "windows" { cp.SendLine("where state") } else { cp.SendLine("which state") } - cp.WaitForInput() + cp.ExpectInput() cp.SendLine("exit") cp.ExpectExitCode(0) - snapshot := strings.Replace(cp.TrimmedSnapshot(), "\n", "", -1) + snapshot := strings.Replace(cp.Output(), "\n", "", -1) if !strings.Contains(snapshot, stateExec) && !strings.Contains(snapshot, stateExecResolved) { suite.Fail(fmt.Sprintf("Snapshot does not include '%s' or '%s', snapshot:\n %s", stateExec, stateExecResolved, snapshot)) } @@ -141,8 +141,8 @@ func (suite *InstallerIntegrationTestSuite) TestInstallIncompatible() { // Run installer with source-path flag (ie. install from this local path) cp := ts.SpawnCmdWithOpts( suite.installerExe, - e2e.WithArgs(installationDir(ts)), - e2e.AppendEnv(constants.DisableUpdates+"=false", sysinfo.VersionOverrideEnvVar+"=10.0.0"), + e2e.OptArgs(installationDir(ts)), + e2e.OptAppendEnv(constants.DisableUpdates+"=false", sysinfo.VersionOverrideEnvVar+"=10.0.0"), ) // Assert output @@ -160,13 +160,13 @@ func (suite *InstallerIntegrationTestSuite) TestInstallNoErrorTips() { cp := ts.SpawnCmdWithOpts( suite.installerExe, - e2e.WithArgs(installationDir(ts), "--activate", "ActiveState/DoesNotExist"), - e2e.AppendEnv(constants.DisableUpdates+"=true"), - e2e.AppendEnv(fmt.Sprintf("%s=%s", constants.OverwriteDefaultSystemPathEnvVarName, dir)), + e2e.OptArgs(installationDir(ts), "--activate", "ActiveState/DoesNotExist"), + e2e.OptAppendEnv(constants.DisableUpdates+"=true"), + e2e.OptAppendEnv(fmt.Sprintf("%s=%s", constants.OverwriteDefaultSystemPathEnvVarName, dir)), ) cp.ExpectExitCode(1) - suite.Assert().NotContains(cp.TrimmedSnapshot(), "Need More Help?", "error tips should not be displayed when invoking installer") + suite.Assert().NotContains(cp.Output(), "Need More Help?", "error tips should not be displayed when invoking installer") } func (suite *InstallerIntegrationTestSuite) TestInstallErrorTips() { @@ -179,17 +179,18 @@ func (suite *InstallerIntegrationTestSuite) TestInstallErrorTips() { cp := ts.SpawnCmdWithOpts( suite.installerExe, - e2e.WithArgs(installationDir(ts), "--activate", "ActiveState-CLI/Python3"), - e2e.AppendEnv(constants.DisableUpdates+"=true"), - e2e.AppendEnv(fmt.Sprintf("%s=%s", constants.OverwriteDefaultSystemPathEnvVarName, dir)), + e2e.OptArgs(installationDir(ts), "--activate", "ActiveState-CLI/Python3"), + e2e.OptAppendEnv(constants.DisableUpdates+"=true"), + e2e.OptAppendEnv(fmt.Sprintf("%s=%s", constants.OverwriteDefaultSystemPathEnvVarName, dir)), ) - cp.WaitForInput() + cp.ExpectInput() cp.SendLine("state command-does-not-exist") - cp.WaitForInput() + cp.ExpectInput() cp.SendLine("exit") - cp.Wait() - suite.Assert().Contains(cp.TrimmedSnapshot(), "Need More Help?", "error tips should be displayed in shell created by installer") + cp.ExpectExit() + suite.Assert().Contains(cp.Output(), "Need More Help?", + "error tips should be displayed in shell created by installer") } func (suite *InstallerIntegrationTestSuite) TestStateTrayRemoval() { @@ -201,12 +202,12 @@ func (suite *InstallerIntegrationTestSuite) TestStateTrayRemoval() { // Install a release version that still has state-tray. version := "0.35.0-SHAb78e2a4" - var cp *termtest.ConsoleProcess + var cp *e2e.SpawnedCmd if runtime.GOOS != "windows" { oneLiner := fmt.Sprintf("sh <(curl -q https://platform.activestate.com/dl/cli/pdli01/install.sh) -f -n -t %s -v %s", dir, version) cp = ts.SpawnCmdWithOpts( - "bash", e2e.WithArgs("-c", oneLiner), - e2e.AppendEnv(fmt.Sprintf("%s=%s", constants.OverwriteDefaultSystemPathEnvVarName, dir)), + "bash", e2e.OptArgs("-c", oneLiner), + e2e.OptAppendEnv(fmt.Sprintf("%s=%s", constants.OverwriteDefaultSystemPathEnvVarName, dir)), ) } else { b, err := httputil.GetDirect("https://platform.activestate.com/dl/cli/pdli01/install.ps1") @@ -215,12 +216,12 @@ func (suite *InstallerIntegrationTestSuite) TestStateTrayRemoval() { ps1File := filepath.Join(ts.Dirs.Work, "install.ps1") suite.Require().NoError(fileutils.WriteFile(ps1File, b)) - cp = ts.SpawnCmdWithOpts("powershell.exe", e2e.WithArgs(ps1File, "-f", "-n", "-t", dir, "-v", version), - e2e.AppendEnv("SHELL="), - e2e.AppendEnv(fmt.Sprintf("%s=%s", constants.OverwriteDefaultSystemPathEnvVarName, dir)), + cp = ts.SpawnCmdWithOpts("powershell.exe", e2e.OptArgs(ps1File, "-f", "-n", "-t", dir, "-v", version), + e2e.OptAppendEnv("SHELL="), + e2e.OptAppendEnv(fmt.Sprintf("%s=%s", constants.OverwriteDefaultSystemPathEnvVarName, dir)), ) } - cp.Expect("Installation Complete", 5*time.Minute) + cp.Expect("Installation Complete", termtest.OptExpectTimeout(5*time.Minute)) // Verify state-tray is there. svcExec, err := installation.ServiceExecFromDir(dir) @@ -233,12 +234,12 @@ func (suite *InstallerIntegrationTestSuite) TestStateTrayRemoval() { // Run the installer, which should remove state-tray and clean up after it. cp = ts.SpawnCmdWithOpts( suite.installerExe, - e2e.WithArgs("-f", "-n", "-t", dir), - e2e.AppendEnv(constants.UpdateBranchEnvVarName+"=release"), - e2e.AppendEnv(fmt.Sprintf("%s=%s", constants.OverwriteDefaultSystemPathEnvVarName, dir)), + e2e.OptArgs("-f", "-n", "-t", dir), + e2e.OptAppendEnv(constants.UpdateBranchEnvVarName+"=release"), + e2e.OptAppendEnv(fmt.Sprintf("%s=%s", constants.OverwriteDefaultSystemPathEnvVarName, dir)), ) - cp.Expect("Installing", 10*time.Second) - cp.Expect("Done", 30*time.Second) + cp.Expect("Installing", termtest.OptExpectTimeout(10*time.Second)) + cp.Expect("Done", termtest.OptExpectTimeout(30*time.Second)) // Verify state-tray is no longer there. suite.NoFileExists(trayExec) @@ -247,8 +248,8 @@ func (suite *InstallerIntegrationTestSuite) TestStateTrayRemoval() { // Verify state can still be run and has a newly updated version. stateExec, err := installation.StateExecFromDir(dir) suite.Require().NoError(err) - cp = ts.SpawnCmdWithOpts(stateExec, e2e.WithArgs("--version")) - suite.Assert().NotContains(cp.TrimmedSnapshot(), version) + cp = ts.SpawnCmdWithOpts(stateExec, e2e.OptArgs("--version")) + suite.Assert().NotContains(cp.Output(), version) cp.ExpectExitCode(0) } @@ -267,8 +268,8 @@ func (suite *InstallerIntegrationTestSuite) TestInstallerOverwriteServiceApp() { cp := ts.SpawnCmdWithOpts( suite.installerExe, - e2e.WithArgs(installationDir(ts)), - e2e.AppendEnv(fmt.Sprintf("%s=%s", constants.AppInstallDirOverrideEnvVarName, appInstallDir)), + e2e.OptArgs(installationDir(ts)), + e2e.OptAppendEnv(fmt.Sprintf("%s=%s", constants.AppInstallDirOverrideEnvVarName, appInstallDir)), ) cp.Expect("Done") cp.SendLine("exit") @@ -277,8 +278,8 @@ func (suite *InstallerIntegrationTestSuite) TestInstallerOverwriteServiceApp() { // State Service.app should be overwritten cleanly without error. cp = ts.SpawnCmdWithOpts( suite.installerExe, - e2e.WithArgs(installationDir(ts)+"2"), - e2e.AppendEnv(fmt.Sprintf("%s=%s", constants.AppInstallDirOverrideEnvVarName, appInstallDir)), + e2e.OptArgs(installationDir(ts)+"2"), + e2e.OptAppendEnv(fmt.Sprintf("%s=%s", constants.AppInstallDirOverrideEnvVarName, appInstallDir)), ) cp.Expect("Done") cp.SendLine("exit") @@ -338,10 +339,10 @@ func installationDir(ts *e2e.Session) string { func (suite *InstallerIntegrationTestSuite) SetupSuite() { rootPath := environment.GetRootPathUnsafe() localPayload := filepath.Join(rootPath, "build", "payload", constants.ToplevelInstallArchiveDir) - suite.Assert().DirExists(localPayload, "locally generated payload exists") + suite.Require().DirExists(localPayload, "locally generated payload exists") installerExe := filepath.Join(localPayload, constants.StateInstallerCmd+osutils.ExeExt) - suite.Assert().FileExists(installerExe, "locally generated installer exists") + suite.Require().FileExists(installerExe, "locally generated installer exists") suite.installerExe = installerExe } diff --git a/cmd/state-svc/test/integration/svc_int_test.go b/cmd/state-svc/test/integration/svc_int_test.go index 2988d24308..7895b0a05c 100644 --- a/cmd/state-svc/test/integration/svc_int_test.go +++ b/cmd/state-svc/test/integration/svc_int_test.go @@ -37,37 +37,37 @@ func (suite *SvcIntegrationTestSuite) TestStartStop() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.SpawnCmdWithOpts(ts.SvcExe, e2e.WithArgs("stop")) + cp := ts.SpawnCmdWithOpts(ts.SvcExe, e2e.OptArgs("stop")) cp.ExpectExitCode(0) - cp = ts.SpawnCmdWithOpts(ts.SvcExe, e2e.WithArgs("status")) + cp = ts.SpawnCmdWithOpts(ts.SvcExe, e2e.OptArgs("status")) cp.Expect("Service cannot be reached") cp.ExpectExitCode(1) - cp = ts.SpawnCmdWithOpts(ts.SvcExe, e2e.WithArgs("start")) + cp = ts.SpawnCmdWithOpts(ts.SvcExe, e2e.OptArgs("start")) cp.Expect("Starting") cp.ExpectExitCode(0) - cp = ts.SpawnCmdWithOpts(ts.SvcExe, e2e.WithArgs("status")) + cp = ts.SpawnCmdWithOpts(ts.SvcExe, e2e.OptArgs("status")) cp.Expect("Checking") // Verify the server is running on its reported port. cp.ExpectRe("Port:\\s+:\\d+\\s") portRe := regexp.MustCompile("Port:\\s+:(\\d+)") - port := portRe.FindStringSubmatch(cp.TrimmedSnapshot())[1] + port := portRe.FindStringSubmatch(cp.Output())[1] _, err := net.Listen("tcp", "localhost:"+port) suite.Error(err) // Verify it created and wrote to its reported log file. cp.ExpectRe("Log:\\s+.+?\\.log") logRe := regexp.MustCompile("Log:\\s+(.+?\\.log)") - logFile := logRe.FindStringSubmatch(cp.TrimmedSnapshot())[1] + logFile := logRe.FindStringSubmatch(cp.Output())[1] suite.True(fileutils.FileExists(logFile), "log file '"+logFile+"' does not exist") suite.True(len(fileutils.ReadFileUnsafe(logFile)) > 0, "log file is empty") cp.ExpectExitCode(0) - cp = ts.SpawnCmdWithOpts(ts.SvcExe, e2e.WithArgs("stop")) + cp = ts.SpawnCmdWithOpts(ts.SvcExe, e2e.OptArgs("stop")) cp.Expect("Stopping") cp.ExpectExitCode(0) time.Sleep(500 * time.Millisecond) // wait for service to stop @@ -94,14 +94,14 @@ func (suite *SvcIntegrationTestSuite) TestSignals() { defer ts.Close() // SIGINT (^C) - cp := ts.SpawnCmdWithOpts(ts.SvcExe, e2e.WithArgs("foreground")) + cp := ts.SpawnCmdWithOpts(ts.SvcExe, e2e.OptArgs("foreground")) cp.Expect("Starting") time.Sleep(1 * time.Second) // wait for the service to start up - cp.Signal(syscall.SIGINT) + cp.Cmd().Process.Signal(syscall.SIGINT) cp.Expect("caught a signal: interrupt") cp.ExpectNotExitCode(0) - cp = ts.SpawnCmdWithOpts(ts.SvcExe, e2e.WithArgs("status")) + cp = ts.SpawnCmdWithOpts(ts.SvcExe, e2e.OptArgs("status")) cp.Expect("Service cannot be reached") cp.ExpectExitCode(1) @@ -109,14 +109,14 @@ func (suite *SvcIntegrationTestSuite) TestSignals() { suite.False(fileutils.TargetExists(sockFile), "socket file was not deleted") // SIGTERM - cp = ts.SpawnCmdWithOpts(ts.SvcExe, e2e.WithArgs("foreground")) + cp = ts.SpawnCmdWithOpts(ts.SvcExe, e2e.OptArgs("foreground")) cp.Expect("Starting") time.Sleep(1 * time.Second) // wait for the service to start up - cp.Signal(syscall.SIGTERM) - suite.NotContains(cp.TrimmedSnapshot(), "caught a signal") + cp.Cmd().Process.Signal(syscall.SIGTERM) + suite.NotContains(cp.Output(), "caught a signal") cp.ExpectExitCode(0) // should exit gracefully - cp = ts.SpawnCmdWithOpts(ts.SvcExe, e2e.WithArgs("status")) + cp = ts.SpawnCmdWithOpts(ts.SvcExe, e2e.OptArgs("status")) cp.Expect("Service cannot be reached") cp.ExpectExitCode(1) @@ -133,20 +133,20 @@ func (suite *SvcIntegrationTestSuite) TestStartDuplicateErrorOutput() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.SpawnCmdWithOpts(ts.SvcExe, e2e.WithArgs("stop")) + cp := ts.SpawnCmdWithOpts(ts.SvcExe, e2e.OptArgs("stop")) cp.ExpectExitCode(0) - cp = ts.SpawnCmdWithOpts(ts.SvcExe, e2e.WithArgs("status")) + cp = ts.SpawnCmdWithOpts(ts.SvcExe, e2e.OptArgs("status")) cp.ExpectNotExitCode(0) - cp = ts.SpawnCmdWithOpts(ts.SvcExe, e2e.WithArgs("start")) + cp = ts.SpawnCmdWithOpts(ts.SvcExe, e2e.OptArgs("start")) cp.ExpectExitCode(0) - cp = ts.SpawnCmdWithOpts(ts.SvcExe, e2e.WithArgs("foreground")) + cp = ts.SpawnCmdWithOpts(ts.SvcExe, e2e.OptArgs("foreground")) cp.Expect("An existing server instance appears to be in use") cp.ExpectExitCode(1) - cp = ts.SpawnCmdWithOpts(ts.SvcExe, e2e.WithArgs("stop")) + cp = ts.SpawnCmdWithOpts(ts.SvcExe, e2e.OptArgs("stop")) cp.ExpectExitCode(0) } @@ -155,12 +155,12 @@ func (suite *SvcIntegrationTestSuite) TestSingleSvc() { ts := e2e.New(suite.T(), false) defer ts.Close() - ts.SpawnCmdWithOpts(ts.SvcExe, e2e.WithArgs("stop")) + ts.SpawnCmdWithOpts(ts.SvcExe, e2e.OptArgs("stop")) time.Sleep(2 * time.Second) // allow for some time to stop the existing available process oldCount := suite.GetNumStateSvcProcesses() // may be non-zero due to non-test state-svc processes (using different sock file) for i := 1; i <= 10; i++ { - go ts.SpawnCmdWithOpts(ts.Exe, e2e.WithArgs("--version")) + go ts.SpawnCmdWithOpts(ts.Exe, e2e.OptArgs("--version")) time.Sleep(50 * time.Millisecond) // do not spam CPU } time.Sleep(2 * time.Second) // allow for some time to spawn the processes @@ -205,19 +205,19 @@ func (suite *SvcIntegrationTestSuite) TestAutostartConfigEnableDisable() { // Toggle it via state tool config. cp := ts.SpawnWithOpts( - e2e.WithArgs("config", "set", constants.AutostartSvcConfigKey, "false"), + e2e.OptArgs("config", "set", constants.AutostartSvcConfigKey, "false"), ) cp.ExpectExitCode(0) - cp = ts.SpawnWithOpts(e2e.WithArgs("config", "get", constants.AutostartSvcConfigKey)) + cp = ts.SpawnWithOpts(e2e.OptArgs("config", "get", constants.AutostartSvcConfigKey)) cp.Expect("false") cp.ExpectExitCode(0) // Toggle it again via state tool config. cp = ts.SpawnWithOpts( - e2e.WithArgs("config", "set", constants.AutostartSvcConfigKey, "true"), + e2e.OptArgs("config", "set", constants.AutostartSvcConfigKey, "true"), ) cp.ExpectExitCode(0) - cp = ts.SpawnWithOpts(e2e.WithArgs("config", "get", constants.AutostartSvcConfigKey)) + cp = ts.SpawnWithOpts(e2e.OptArgs("config", "get", constants.AutostartSvcConfigKey)) cp.Expect("true") cp.ExpectExitCode(0) } diff --git a/go.mod b/go.mod index 2f1af693a2..b14569794e 100644 --- a/go.mod +++ b/go.mod @@ -7,8 +7,7 @@ replace cloud.google.com/go => cloud.google.com/go v0.110.0 require ( github.com/99designs/gqlgen v0.17.19 github.com/ActiveState/go-ogle-analytics v0.0.0-20170510030904-9b3f14901527 - github.com/ActiveState/termtest v0.7.2 - github.com/ActiveState/termtest/expect v0.7.0 + github.com/ActiveState/termtest v0.7.3-0.20230914171339-6e6462ec3e3f github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 github.com/alecthomas/participle/v2 v2.0.0 github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 @@ -52,19 +51,19 @@ require ( github.com/posener/wstest v0.0.0-20180216222922-04b166ca0bf1 github.com/rollbar/rollbar-go v1.1.0 github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0 - github.com/shirou/gopsutil/v3 v3.22.7 + github.com/shirou/gopsutil/v3 v3.23.8 github.com/skratchdot/open-golang v0.0.0-20190104022628-a2dfa6d0dab6 github.com/spf13/cast v1.3.0 github.com/spf13/cobra v1.1.1 github.com/spf13/pflag v1.0.5 - github.com/stretchr/testify v1.8.1 + github.com/stretchr/testify v1.8.4 github.com/thoas/go-funk v0.8.0 github.com/vbauerster/mpb/v7 v7.1.5 github.com/vektah/gqlparser/v2 v2.5.1 go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 golang.org/x/crypto v0.7.0 golang.org/x/net v0.8.0 - golang.org/x/sys v0.6.0 + golang.org/x/sys v0.11.0 golang.org/x/term v0.6.0 golang.org/x/text v0.8.0 gopkg.in/AlecAivazis/survey.v1 v1.8.8 @@ -77,9 +76,12 @@ require ( require github.com/ActiveState/graphql v0.0.0-20230719154233-6949037a6e48 require ( - github.com/ActiveState/termtest/conpty v0.5.0 // indirect - github.com/ActiveState/termtest/xpty v0.6.0 // indirect - github.com/ActiveState/vt10x v1.3.1 // indirect + github.com/ActiveState/pty v0.0.0-20230628221854-6fb90eb08a14 // indirect + github.com/hinshun/vt10x v0.0.0-20220301184237-5011da428d02 // indirect + github.com/shoenig/go-m1cpu v0.1.6 // indirect +) + +require ( github.com/BurntSushi/toml v1.2.1 // indirect github.com/Netflix/go-expect v0.0.0-20201125194554-85d881c3777e // indirect github.com/PuerkitoBio/purell v1.1.1 // indirect @@ -111,7 +113,6 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd // indirect - github.com/kr/pty v1.1.8 // indirect github.com/labstack/gommon v0.3.1 // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/mailru/easyjson v0.7.7 // indirect @@ -135,15 +136,15 @@ require ( github.com/sergi/go-diff v1.3.1 github.com/src-d/gcfg v1.4.0 // indirect github.com/stretchr/objx v0.5.0 // indirect - github.com/tklauser/go-sysconf v0.3.10 // indirect - github.com/tklauser/numcpus v0.4.0 // indirect + github.com/tklauser/go-sysconf v0.3.12 // indirect + github.com/tklauser/numcpus v0.6.1 // indirect github.com/trivago/tgo v1.0.7 // indirect github.com/ulikunitz/xz v0.5.11 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.1 // indirect github.com/xanzy/ssh-agent v0.2.1 // indirect github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect - github.com/yusufpapurcu/wmi v1.2.2 // indirect + github.com/yusufpapurcu/wmi v1.2.3 // indirect go.mongodb.org/mongo-driver v1.5.3 // indirect golang.org/x/mod v0.8.0 // indirect golang.org/x/time v0.1.0 // indirect diff --git a/go.sum b/go.sum index ed2481c866..723da87d71 100644 --- a/go.sum +++ b/go.sum @@ -343,16 +343,10 @@ github.com/ActiveState/go-ogle-analytics v0.0.0-20170510030904-9b3f14901527 h1:l github.com/ActiveState/go-ogle-analytics v0.0.0-20170510030904-9b3f14901527/go.mod h1:/9SyzKLlJSuIa7WAsLUUhHqTK9+PtZD8cKF8G4SLpa0= github.com/ActiveState/graphql v0.0.0-20230719154233-6949037a6e48 h1:UCx/ObpVRgC4fp2OlJM2iNdMMu+K87/aPxKrQ1WRLj4= github.com/ActiveState/graphql v0.0.0-20230719154233-6949037a6e48/go.mod h1:NhUbNQ8UpfnC6nZvZ8oThqYSCE/G8FQp9JUrK9jXJs0= -github.com/ActiveState/termtest v0.7.2 h1:vNPMpI2AyZnLZzZn/CRpMZzIuVL0XhaTLA4qyghIGF8= -github.com/ActiveState/termtest v0.7.2/go.mod h1:krmYxOsjckZpOKlHI+wDqaGkpOBtM55Lr8YZckriE+0= -github.com/ActiveState/termtest/conpty v0.5.0 h1:JLUe6YDs4Jw4xNPCU+8VwTpniYOGeKzQg4SM2YHQNA8= -github.com/ActiveState/termtest/conpty v0.5.0/go.mod h1:LO4208FLsxw6DcNZ1UtuGUMW+ga9PFtX4ntv8Ymg9og= -github.com/ActiveState/termtest/expect v0.7.0 h1:VNrcfXTHXXoe7i+3WgF5QJhstQLGP4saj+XYM9ZzBvY= -github.com/ActiveState/termtest/expect v0.7.0/go.mod h1:64QuJvMtMu7+H5U+5TSMBxAs1FAaLvRIyN7WPOICido= -github.com/ActiveState/termtest/xpty v0.6.0 h1:L9c17TDfy+ed+tY5cMOErn0n2EYG4tj8StdxHmoPok8= -github.com/ActiveState/termtest/xpty v0.6.0/go.mod h1:MmTm/62Ajq+D92emHq8LOu9Q+2+pkBurDLahkUP6Odg= -github.com/ActiveState/vt10x v1.3.1 h1:7qi8BGXUEBghzBxfXSY0J77etO+L95PZQlwD7ay2mn0= -github.com/ActiveState/vt10x v1.3.1/go.mod h1:8wJKd36c9NmCfGyPyOJmkvyIMvbUPfHkfdS8zZlK19s= +github.com/ActiveState/pty v0.0.0-20230628221854-6fb90eb08a14 h1:RdhhSiwmgyUaaF2GBNrbqTwE5SM+MaVjwf91Ua+CK8c= +github.com/ActiveState/pty v0.0.0-20230628221854-6fb90eb08a14/go.mod h1:5mM6vNRQwshCjlkOnVpwC//4ZpkiC6nmZr8lPOxJdXs= +github.com/ActiveState/termtest v0.7.3-0.20230914171339-6e6462ec3e3f h1:qvVEJlgKYo2NArClTlzSvn/xovhghZv8CJiV7My1TnI= +github.com/ActiveState/termtest v0.7.3-0.20230914171339-6e6462ec3e3f/go.mod h1:RyWp2NaaTrVAa+XjMHpKAqwBFWbL6wE12HQxiZNGAqU= github.com/AlecAivazis/survey/v2 v2.0.5/go.mod h1:WYBhg6f0y/fNYUuesWQc0PKbJcEliGcYHB9sNT3Bg74= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= @@ -362,7 +356,6 @@ github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc= -github.com/Netflix/go-expect v0.0.0-20200312175327-da48e75238e2/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc= github.com/Netflix/go-expect v0.0.0-20201125194554-85d881c3777e h1:YYUPbL3iB9+Y/JYEXjCi9AolqiKIIJX/2aRR9TuKD6w= github.com/Netflix/go-expect v0.0.0-20201125194554-85d881c3777e/go.mod h1:68ORG0HSEWDuH5Eh73AFbYWZ1zT4Y+b0vhOa+vZRUdI= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= @@ -409,8 +402,6 @@ github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:o github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ= github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= -github.com/autarch/testify v1.2.2 h1:9Q9V6zqhP7R6dv+zRUddv6kXKLo6ecQhnFRFWM71i1c= -github.com/autarch/testify v1.2.2/go.mod h1:oDbHKfFv2/D5UtVrxkk90OKcb6P4/AqF1Pcf6ZbvDQo= github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48= github.com/aws/aws-sdk-go v1.45.1 h1:PXuxDZIo/Y9Bvtg2t055+dY4hRwNAEcq6bUMv9fXcjk= github.com/aws/aws-sdk-go v1.45.1/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= @@ -502,8 +493,6 @@ github.com/gammazero/deque v0.0.0-20200721202602-07291166fe33 h1:UG4wNrJX9xSKnm/ github.com/gammazero/deque v0.0.0-20200721202602-07291166fe33/go.mod h1:D90+MBHVc9Sk1lJAbEVgws0eYEurY4mv2TDso3Nxh3w= github.com/gammazero/workerpool v1.1.1 h1:MN29GcZtZZAgzTU+Zk54Y+J9XkE54MoXON/NCZvNulo= github.com/gammazero/workerpool v1.1.1/go.mod h1:5BN0IJVRjSFAypo9QTJCaWdijjNz9Jjl6VFS1PRjCeg= -github.com/gdamore/encoding v0.0.0-20151215212835-b23993cbb635/go.mod h1:yrQYJKKDTrHmbYxI7CYi+/hbdiDT2m4Hj+t0ikCjsrQ= -github.com/gdamore/tcell v1.0.1-0.20180608172421-b3cebc399d6f/go.mod h1:tqyG50u7+Ctv1w5VX67kLzKcj9YXR/JSBZQq/+mLl1A= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= @@ -756,8 +745,8 @@ github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A= -github.com/hinshun/vt10x v0.0.0-20180809195222-d55458df857c h1:kp3AxgXgDOmIJFR7bIwqFhwJ2qWar8tEQSE5XXhCfVk= -github.com/hinshun/vt10x v0.0.0-20180809195222-d55458df857c/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A= +github.com/hinshun/vt10x v0.0.0-20220301184237-5011da428d02 h1:AgcIVYPa6XJnU3phs104wLj8l5GEththEw6+F79YsIY= +github.com/hinshun/vt10x v0.0.0-20220301184237-5011da428d02/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= @@ -818,7 +807,6 @@ github.com/labstack/echo/v4 v4.9.0/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20L github.com/labstack/gommon v0.3.1 h1:OomWaJXm7xR6L1HmEtGyQf26TEn7V6X88mktX9kee9o= github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= github.com/logrusorgru/aurora/v3 v3.0.0/go.mod h1:vsR12bk5grlLvLXAYrBsb5Oc/N+LxAlxggSjiwMnCUc= -github.com/lucasb-eyer/go-colorful v0.0.0-20180526135729-345fbb3dbcdb/go.mod h1:NXg0ArsFk0Y01623LgUqoqcouGDB+PwCCQlrwrG6xJ4= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= @@ -850,7 +838,6 @@ github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= @@ -956,8 +943,12 @@ github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0 h1:Xuk8ma/ibJ1fOy4Ee11vHhUFHQNpHhrBneOCNHVXS5w= github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0/go.mod h1:7AwjWCpdPhkSmNAgUv5C7EJ4AbmjEB3r047r3DXWu3Y= -github.com/shirou/gopsutil/v3 v3.22.7 h1:flKnuCMfUUrO+oAvwAd6GKZgnPzr098VA/UJ14nhJd4= -github.com/shirou/gopsutil/v3 v3.22.7/go.mod h1:s648gW4IywYzUfE/KjXxUsqrqx/T2xO5VqOXxONeRfI= +github.com/shirou/gopsutil/v3 v3.23.8 h1:xnATPiybo6GgdRoC4YoGnxXZFRc3dqQTGi73oLvvBrE= +github.com/shirou/gopsutil/v3 v3.23.8/go.mod h1:7hmCaBn+2ZwaZOr6jmPBZDfawwMGuo1id3C6aM8EDqQ= +github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= +github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= +github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= +github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= @@ -1000,17 +991,18 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/thoas/go-funk v0.8.0 h1:JP9tKSvnpFVclYgDM0Is7FD9M4fhPvqA0s0BsXmzSRQ= github.com/thoas/go-funk v0.8.0/go.mod h1:+IWnUfUmFO1+WVYQWQtIJHeRRdaIyyYglZN7xzUPe4Q= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/tklauser/go-sysconf v0.3.10 h1:IJ1AZGZRWbY8T5Vfk04D9WOA5WSejdflXxP03OUqALw= -github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk= -github.com/tklauser/numcpus v0.4.0 h1:E53Dm1HjH1/R2/aoCtXtPgzmElmn51aOkhCFSuZq//o= -github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ= +github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= +github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= +github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/trivago/tgo v1.0.7 h1:uaWH/XIy9aWYWpjm2CU3RpcqZXmX2ysQ9/Go+d9gyrM= github.com/trivago/tgo v1.0.7/go.mod h1:w4dpD+3tzNIIiIfkWWa85w5/B77tlvdZckQ+6PkFnhc= @@ -1043,8 +1035,8 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= -github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= +github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= @@ -1065,6 +1057,7 @@ go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1082,7 +1075,6 @@ golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200427165652-729f1e841bcc/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= @@ -1228,13 +1220,9 @@ golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200428200454-593003d681fa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200821140526-fda516888d29/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1268,14 +1256,16 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220721230656-c6bc011c0c49/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1492,7 +1482,6 @@ google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/AlecAivazis/survey.v1 v1.8.8 h1:5UtTowJZTz1j7NxVzDGKTz6Lm9IWm8DDF6b7a2wq9VY= gopkg.in/AlecAivazis/survey.v1 v1.8.8/go.mod h1:CaHjv79TCgAvXMSFJSVgonHXYWxnhzI3eoHtnX5UgUo= -gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0/go.mod h1:OdE7CF6DbADk7lN8LIKRzRJTTZXIjtWgA5THM5lhBAw= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/internal/locale/locales/en-us.yaml b/internal/locale/locales/en-us.yaml index e3db0c82c7..8dd66b033a 100644 --- a/internal/locale/locales/en-us.yaml +++ b/internal/locale/locales/en-us.yaml @@ -2065,3 +2065,5 @@ err_edit_local_checkouts: other: Could not update local checkouts err_edit_project_mapping: other: Could not update project mapping +notice_runtime_disabled: + other: Skipping runtime setup because it was disabled by an environment variable \ No newline at end of file diff --git a/internal/testhelpers/e2e/session.go b/internal/testhelpers/e2e/session.go index 0e5ac5a653..a7ac73c423 100644 --- a/internal/testhelpers/e2e/session.go +++ b/internal/testhelpers/e2e/session.go @@ -5,6 +5,7 @@ import ( "io/fs" "io/ioutil" "os" + "os/exec" "path/filepath" "regexp" "runtime" @@ -12,6 +13,12 @@ import ( "testing" "time" + "github.com/ActiveState/termtest" + "github.com/go-openapi/strfmt" + "github.com/google/uuid" + "github.com/phayes/permbits" + "github.com/stretchr/testify/require" + "github.com/ActiveState/cli/internal/condition" "github.com/ActiveState/cli/internal/config" "github.com/ActiveState/cli/internal/constants" @@ -33,12 +40,6 @@ import ( "github.com/ActiveState/cli/pkg/platform/authentication" "github.com/ActiveState/cli/pkg/platform/model" "github.com/ActiveState/cli/pkg/project" - "github.com/ActiveState/termtest" - "github.com/ActiveState/termtest/expect" - "github.com/go-openapi/strfmt" - "github.com/google/uuid" - "github.com/phayes/permbits" - "github.com/stretchr/testify/require" ) // Session represents an end-to-end testing session during which several console process can be spawned and tested @@ -47,7 +48,6 @@ import ( // The session is approximately the equivalent of a terminal session, with the // main difference processes in this session are not spawned by a shell. type Session struct { - cp *termtest.ConsoleProcess Dirs *Dirs Env []string retainDirs bool @@ -58,15 +58,7 @@ type Session struct { Exe string SvcExe string ExecutorExe string -} - -// Options for spawning a testable terminal process -type Options struct { - termtest.Options - // removes write-permissions in the bin directory from which executables are spawned. - NonWriteableBinDir bool - // expect the process to run in background (will not be stopped by subsequent processes) - BackgroundProcess bool + spawned []*SpawnedCmd } var ( @@ -75,7 +67,6 @@ var ( PersistentToken string defaultTimeout = 40 * time.Second - authnTimeout = 40 * time.Second ) func init() { @@ -187,6 +178,7 @@ func new(t *testing.T, retainDirs, updatePath bool, extraEnv ...string) *Session constants.OptinUnstableEnvVarName + "=true", constants.ServiceSockDir + "=" + dirs.SockRoot, constants.HomeEnvVarName + "=" + dirs.HomeDir, + "NO_COLOR=true", }...) if updatePath { @@ -220,76 +212,125 @@ func NewNoPathUpdate(t *testing.T, retainDirs bool, extraEnv ...string) *Session return new(t, retainDirs, false, extraEnv...) } +func (s *Session) SetT(t *testing.T) { + s.t = t +} + func (s *Session) ClearCache() error { return os.RemoveAll(s.Dirs.Cache) } // Spawn spawns the state tool executable to be tested with arguments -func (s *Session) Spawn(args ...string) *termtest.ConsoleProcess { - return s.SpawnCmdWithOpts(s.Exe, WithArgs(args...)) +func (s *Session) Spawn(args ...string) *SpawnedCmd { + return s.SpawnCmdWithOpts(s.Exe, OptArgs(args...)) } // SpawnWithOpts spawns the state tool executable to be tested with arguments -func (s *Session) SpawnWithOpts(opts ...SpawnOptions) *termtest.ConsoleProcess { +func (s *Session) SpawnWithOpts(opts ...SpawnOptSetter) *SpawnedCmd { return s.SpawnCmdWithOpts(s.Exe, opts...) } // SpawnCmd executes an executable in a pseudo-terminal for integration tests -func (s *Session) SpawnCmd(cmdName string, args ...string) *termtest.ConsoleProcess { - return s.SpawnCmdWithOpts(cmdName, WithArgs(args...)) +func (s *Session) SpawnCmd(cmdName string, args ...string) *SpawnedCmd { + return s.SpawnCmdWithOpts(cmdName, OptArgs(args...)) } // SpawnShellWithOpts spawns the given shell and options in interactive mode. -func (s *Session) SpawnShellWithOpts(shell Shell, opts ...SpawnOptions) *termtest.ConsoleProcess { +func (s *Session) SpawnShellWithOpts(shell Shell, opts ...SpawnOptSetter) *SpawnedCmd { if shell != Cmd { - opts = append(opts, AppendEnv("SHELL="+string(shell))) + opts = append(opts, OptAppendEnv("SHELL="+string(shell))) } + opts = append(opts, OptRunInsideShell(false)) return s.SpawnCmdWithOpts(string(shell), opts...) } // SpawnCmdWithOpts executes an executable in a pseudo-terminal for integration tests -// Arguments and other parameters can be specified by specifying SpawnOptions -func (s *Session) SpawnCmdWithOpts(exe string, opts ...SpawnOptions) *termtest.ConsoleProcess { - if s.cp != nil { - s.cp.Close() - } +// Arguments and other parameters can be specified by specifying SpawnOptSetter +func (s *Session) SpawnCmdWithOpts(exe string, optSetters ...SpawnOptSetter) *SpawnedCmd { + spawnOpts := NewSpawnOpts() + spawnOpts.Env = s.Env + spawnOpts.Dir = s.Dirs.Work + + spawnOpts.TermtestOpts = append(spawnOpts.TermtestOpts, + termtest.OptErrorHandler(func(tt *termtest.TermTest, err error) error { + s.t.Fatal(s.DebugMessage(errs.JoinMessage(err))) + return err + }), + termtest.OptDefaultTimeout(defaultTimeout), + termtest.OptCols(140), + termtest.OptRows(30), // Needs to be able to accommodate most JSON output + ) - env := s.Env + // Work around issue where multiline values sometimes have the wrong line endings + // See for example TestBranch_List + // https://activestatef.atlassian.net/browse/DX-2169 + spawnOpts.TermtestOpts = append(spawnOpts.TermtestOpts, + termtest.OptNormalizedLineEnds(true), + ) - pOpts := Options{ - Options: termtest.Options{ - DefaultTimeout: defaultTimeout, - Environment: env, - WorkDirectory: s.Dirs.Work, - RetainWorkDir: true, - ObserveExpect: observeExpectFn(s), - ObserveSend: observeSendFn(s), - }, - NonWriteableBinDir: false, + for _, optSet := range optSetters { + optSet(&spawnOpts) + } + + var shell string + var args []string + if spawnOpts.RunInsideShell { + switch runtime.GOOS { + case "windows": + shell = Cmd + // /C = next argument is command that will be ran + args = []string{"/C"} + case "darwin": + shell = "zsh" + // -i = interactive mode + // -c = next argument is command that will be ran + args = []string{"-i", "-c"} + default: + shell = "bash" + args = []string{"-i", "-c"} + } + if len(spawnOpts.Args) == 0 { + args = append(args, fmt.Sprintf(`"%s"`, exe)) + } else { + if shell == Cmd { + aa := spawnOpts.Args + for i, a := range aa { + aa[i] = strings.ReplaceAll(a, " ", "^ ") + } + // Windows is weird, it doesn't seem to let you quote arguments, so instead we need to escape spaces + // which on Windows is done with the '^' character. + args = append(args, fmt.Sprintf(`%s %s`, strings.ReplaceAll(exe, " ", "^ "), strings.Join(aa, " "))) + } else { + args = append(args, fmt.Sprintf(`"%s" "%s"`, exe, strings.Join(spawnOpts.Args, `" "`))) + } + } + } else { + shell = exe + args = spawnOpts.Args } - for _, opt := range opts { - opt(&pOpts) - } + cmd := exec.Command(shell, args...) - pOpts.Options.CmdName = exe + cmd.Env = spawnOpts.Env - if pOpts.NonWriteableBinDir { - // make bin dir read-only - os.Chmod(s.Dirs.Bin, 0555) - } else { - os.Chmod(s.Dirs.Bin, 0777) + if spawnOpts.Dir != "" { + cmd.Dir = spawnOpts.Dir } - console, err := termtest.New(pOpts.Options) + tt, err := termtest.New(cmd, spawnOpts.TermtestOpts...) require.NoError(s.t, err) - if !pOpts.BackgroundProcess { - s.cp = console - } - logging.Debug("Spawning CMD: %s, args: %v", pOpts.Options.CmdName, pOpts.Options.Args) + spawn := &SpawnedCmd{tt, spawnOpts} - return console + s.spawned = append(s.spawned, spawn) + + cmdArgs := spawnOpts.Args + if spawnOpts.HideCmdArgs { + cmdArgs = []string{""} + } + logging.Debug("Spawning CMD: %s, args: %v", exe, cmdArgs) + + return spawn } // PrepareActiveStateYAML creates an activestate.yaml in the session's work directory from the @@ -329,12 +370,12 @@ func (s *Session) PrepareFile(path, contents string) { // LoginAsPersistentUser is a common test case after which an integration test user should be logged in to the platform func (s *Session) LoginAsPersistentUser() { p := s.SpawnWithOpts( - WithArgs(tagsuite.Auth, "--username", PersistentUsername, "--password", PersistentPassword), + OptArgs(tagsuite.Auth, "--username", PersistentUsername, "--password", PersistentPassword), // as the command line includes a password, we do not print the executed command, so the password does not get logged - HideCmdLine(), + OptHideArgs(), ) - p.Expect("logged in", authnTimeout) + p.Expect("logged in", termtest.OptExpectTimeout(defaultTimeout)) p.ExpectExitCode(0) } @@ -423,51 +464,45 @@ func (s *Session) DebugMessage(prefix string) string { prefix = prefix + "\n" } - snapshot := "" - if s.cp != nil { - snapshot = s.cp.Snapshot() + output := map[string]string{} + for _, spawn := range s.spawned { + name := spawn.Cmd().String() + if spawn.opts.HideCmdArgs { + name = spawn.Cmd().Path + } + output[name] = strings.TrimSpace(spawn.Snapshot()) } v, err := strutils.ParseTemplate(` -{{.Prefix}}{{.A}}Stack: -{{.Stacktrace}}{{.Z}} -{{.A}}Terminal snapshot: -{{.FullSnapshot}}{{.Z}} -{{.Logs}} +{{.Prefix}}Stack: +{{.Stacktrace}} +{{range $title, $value := .Outputs}} +{{$.A}}Snapshot for Cmd '{{$title}}': +{{$value}} +{{$.Z}} +{{end}} +{{range $title, $value := .Logs}} +{{$.A}}Log '{{$title}}': +{{$value}} +{{$.Z}} +{{else}} +No logs +{{end}} `, map[string]interface{}{ - "Prefix": prefix, - "Stacktrace": stacktrace.Get().String(), - "FullSnapshot": snapshot, - "Logs": s.DebugLogs(), - "A": sectionStart, - "Z": sectionEnd, + "Prefix": prefix, + "Stacktrace": stacktrace.Get().String(), + "Outputs": output, + "Logs": s.DebugLogs(), + "A": sectionStart, + "Z": sectionEnd, }, nil) if err != nil { - s.t.Fatalf("Parsing template failed: %s", err) + s.t.Fatalf("Parsing template failed: %s", errs.JoinMessage(err)) } return v } -func observeExpectFn(s *Session) expect.ExpectObserver { - return func(matchers []expect.Matcher, ms *expect.MatchState, err error) { - if err == nil { - return - } - - var value string - var sep string - for _, matcher := range matchers { - value += fmt.Sprintf("%s%v", sep, matcher.Criteria()) - sep = ", " - } - - s.t.Fatal(s.DebugMessage(fmt.Sprintf(` -Could not meet expectation: '%s' -Error: %s`, value, err))) - } -} - // Close removes the temporary directory unless RetainDirs is specified func (s *Session) Close() error { // stop service if it exists @@ -483,9 +518,7 @@ func (s *Session) Close() error { defer s.Dirs.Close() } - if s.cp != nil { - s.cp.Close() - } + s.spawned = []*SpawnedCmd{} if os.Getenv("PLATFORM_API_TOKEN") == "" { s.t.Log("PLATFORM_API_TOKEN env var not set, not running suite tear down") @@ -614,10 +647,26 @@ func (s *Session) LogFiles() []string { return result } -func (s *Session) DebugLogs() string { +func (s *Session) DebugLogs() map[string]string { + result := map[string]string{} + logDir := filepath.Join(s.Dirs.Config, "logs") if !fileutils.DirExists(logDir) { - return "No logs found in " + logDir + return result + } + + for _, path := range s.LogFiles() { + result[filepath.Base(path)] = string(fileutils.ReadFileUnsafe(path)) + } + + return result +} + +func (s *Session) DebugLogsDump() string { + logs := s.DebugLogs() + + if len(logs) == 0 { + return "No logs found in " + filepath.Join(s.Dirs.Config, "logs") } var sectionStart, sectionEnd string @@ -628,8 +677,8 @@ func (s *Session) DebugLogs() string { } result := "Logs:\n" - for _, path := range s.LogFiles() { - result += fmt.Sprintf("%s%s:\n%s%s\n", sectionStart, filepath.Base(path), fileutils.ReadFileUnsafe(path), sectionEnd) + for name, log := range logs { + result += fmt.Sprintf("%s%s:\n%s%s\n", sectionStart, name, log, sectionEnd) } return result diff --git a/internal/testhelpers/e2e/spawn.go b/internal/testhelpers/e2e/spawn.go index 6609acb090..33aff86cef 100644 --- a/internal/testhelpers/e2e/spawn.go +++ b/internal/testhelpers/e2e/spawn.go @@ -1,47 +1,177 @@ package e2e -type SpawnOptions func(*Options) error +import ( + "fmt" + "path/filepath" + "regexp" + "runtime" + "strings" + "time" -func WithArgs(args ...string) SpawnOptions { - return func(opts *Options) error { - opts.Options.Args = args - return nil + "github.com/ActiveState/termtest" + + "github.com/ActiveState/cli/internal/errs" + "github.com/ActiveState/cli/internal/osutils" +) + +type SpawnedCmd struct { + *termtest.TermTest + opts SpawnOpts +} + +func (s *SpawnedCmd) WorkDirectory() string { + return s.TermTest.Cmd().Dir +} + +func (s *SpawnedCmd) Wait() error { + return s.TermTest.Wait(30 * time.Second) +} + +func (s *SpawnedCmd) Executable() string { + return s.TermTest.Cmd().Path +} + +// StrippedSnapshot returns the snapshot with trimmed whitespace and stripped line endings +// Mainly intended for JSON parsing +func (s *SpawnedCmd) StrippedSnapshot() string { + return strings.Trim(strings.ReplaceAll(s.TermTest.Snapshot(), "\n", ""), "\x00\x20\x0a\x0d") +} + +// ExpectRe takes a string rather than an already compiled regex, so that we can handle regex compilation failures +// through our error handling chain rather than have it fail on eg. a panic through regexp.MustCompile, or needing +// to manually error check it before sending it to ExpectRe. +func (s *SpawnedCmd) ExpectRe(v string, opts ...termtest.SetExpectOpt) error { + expectOpts, err := termtest.NewExpectOpts(opts...) + if err != nil { + err = fmt.Errorf("could not create expect options: %w", err) + return s.ExpectErrorHandler(&err, expectOpts) + } + + rx, err := regexp.Compile(v) + if err != nil { + err = errs.Wrap(err, "ExpectRe received invalid regex string") + return s.ExpectErrorHandler(&err, expectOpts) + } + return s.TermTest.ExpectRe(rx, opts...) +} + +func (s *SpawnedCmd) ExpectInput(opts ...termtest.SetExpectOpt) error { + expectOpts, err := termtest.NewExpectOpts(opts...) + if err != nil { + err = fmt.Errorf("could not create expect options: %w", err) + return s.ExpectErrorHandler(&err, expectOpts) + } + + cmdName := strings.TrimSuffix(strings.ToLower(filepath.Base(s.Cmd().Path)), ".exe") + + shellName := "" + envMap := osutils.EnvSliceToMap(s.Cmd().Env) + if v, ok := envMap["SHELL"]; ok { + shellName = strings.TrimSuffix(strings.ToLower(filepath.Base(v)), ".exe") + } + + send := `echo $'expect\'input from posix shell'` + expect := `expect'input from posix shell` + if cmdName != "bash" && shellName != "bash" && runtime.GOOS == "windows" { + send = `echo ^` + expect = `` + } + + // Termtest internal functions already implement error handling + if err := s.SendLine(send); err != nil { + return fmt.Errorf("could not send line to terminal: %w", err) + } + + return s.Expect(expect, opts...) +} + +func (s *SpawnedCmd) Send(value string) error { + if runtime.GOOS == "windows" { + // Work around race condition - on Windows it appears more likely to happen + // https://activestatef.atlassian.net/browse/DX-2171 + time.Sleep(100 * time.Millisecond) + } + return s.TermTest.Send(value) +} + +func (s *SpawnedCmd) SendLine(value string) error { + if runtime.GOOS == "windows" { + // Work around race condition - on Windows it appears more likely to happen + // https://activestatef.atlassian.net/browse/DX-2171 + time.Sleep(100 * time.Millisecond) + } + return s.TermTest.SendLine(value) +} + +func (s *SpawnedCmd) SendEnter() error { + return s.SendLine("") +} + +func (s *SpawnedCmd) SendKeyUp() error { + return s.Send(string([]byte{0033, '[', 'A'})) +} + +func (s *SpawnedCmd) SendKeyDown() error { + return s.Send(string([]byte{0033, '[', 'B'})) +} + +func (s *SpawnedCmd) SendKeyRight() error { + return s.Send(string([]byte{0033, '[', 'C'})) +} + +func (s *SpawnedCmd) SendKeyLeft() error { + return s.Send(string([]byte{0033, '[', 'D'})) +} + +type SpawnOpts struct { + Args []string + Env []string + Dir string + TermtestOpts []termtest.SetOpt + HideCmdArgs bool + RunInsideShell bool +} + +func NewSpawnOpts() SpawnOpts { + return SpawnOpts{ + RunInsideShell: false, + } +} + +type SpawnOptSetter func(opts *SpawnOpts) + +func OptArgs(args ...string) SpawnOptSetter { + return func(opts *SpawnOpts) { + opts.Args = args } } -func WithWorkDirectory(wd string) SpawnOptions { - return func(opts *Options) error { - opts.Options.WorkDirectory = wd - return nil +func OptWD(wd string) SpawnOptSetter { + return func(opts *SpawnOpts) { + opts.Dir = wd } } -func AppendEnv(env ...string) SpawnOptions { - return func(opts *Options) error { - opts.Options.Environment = append(opts.Options.Environment, env...) - return nil +func OptAppendEnv(env ...string) SpawnOptSetter { + return func(opts *SpawnOpts) { + opts.Env = append(opts.Env, env...) } } -func HideCmdLine() SpawnOptions { - return func(opts *Options) error { - opts.Options.HideCmdLine = true - return nil +func OptTermTest(opt ...termtest.SetOpt) SpawnOptSetter { + return func(opts *SpawnOpts) { + opts.TermtestOpts = append(opts.TermtestOpts, opt...) } } -// NonWriteableBinDir removes the write permission from the directory where the executables are run from. -// This can be used to simulate an installation in a global installation directory that requires super-user rights. -func NonWriteableBinDir() SpawnOptions { - return func(opts *Options) error { - opts.NonWriteableBinDir = true - return nil +func OptHideArgs() SpawnOptSetter { + return func(opts *SpawnOpts) { + opts.HideCmdArgs = true } } -func BackgroundProcess() SpawnOptions { - return func(opts *Options) error { - opts.BackgroundProcess = true - return nil +func OptRunInsideShell(v bool) SpawnOptSetter { + return func(opts *SpawnOpts) { + opts.RunInsideShell = v } } diff --git a/pkg/platform/runtime/runtime.go b/pkg/platform/runtime/runtime.go index fb63df3c03..7e36db21e4 100644 --- a/pkg/platform/runtime/runtime.go +++ b/pkg/platform/runtime/runtime.go @@ -9,6 +9,8 @@ import ( "strconv" "strings" + "golang.org/x/net/context" + "github.com/ActiveState/cli/internal/analytics" anaConsts "github.com/ActiveState/cli/internal/analytics/constants" "github.com/ActiveState/cli/internal/analytics/dimensions" @@ -32,7 +34,6 @@ import ( "github.com/ActiveState/cli/pkg/platform/runtime/setup/events" "github.com/ActiveState/cli/pkg/platform/runtime/store" "github.com/ActiveState/cli/pkg/project" - "golang.org/x/net/context" ) type Runtime struct { @@ -83,8 +84,8 @@ func New(target setup.Targeter, an analytics.Dispatcher, svcm *model.SvcModel, a logging.Debug("Initializing runtime for: %s/%s@%s", target.Owner(), target.Name(), target.CommitUUID()) if strings.ToLower(os.Getenv(constants.DisableRuntime)) == "true" { - fmt.Fprintln(os.Stderr, locale.Tl("notice_runtime_disabled", "Skipping runtime setup because it was disabled by an environment variable")) - return &Runtime{disabled: true, target: target}, nil + fmt.Fprintln(os.Stderr, locale.T("notice_runtime_disabled")) + return &Runtime{disabled: true, target: target, analytics: an}, nil } recordAttempt(an, target) an.Event(anaConsts.CatRuntimeDebug, anaConsts.ActRuntimeStart, &dimensions.Values{ diff --git a/test/automation/invite_neg_automation_test.go b/test/automation/invite_neg_automation_test.go index 97a1876f95..de3bf74fde 100644 --- a/test/automation/invite_neg_automation_test.go +++ b/test/automation/invite_neg_automation_test.go @@ -22,12 +22,12 @@ func (suite *InviteNegativeAutomationTestSuite) TestInvite_NotInProject() { // Single email invite cp := ts.Spawn("invite", "qatesting+3@activestate.com") - cp.ExpectLongString("No activestate.yaml file exists in the current working directory") + cp.Expect("No activestate.yaml file exists in the current working directory") cp.ExpectExitCode(1) // Multiple emails invite cp = ts.Spawn("invite", "qatesting+3@activestate.com,", "qatesting+4@activestate.com") - cp.ExpectLongString("No activestate.yaml file exists in the current working directory") + cp.Expect("No activestate.yaml file exists in the current working directory") cp.ExpectExitCode(1) } @@ -42,7 +42,7 @@ func (suite *InviteNegativeAutomationTestSuite) TestInvite_NotAuthPublic() { suite.Require().NoError(fileutils.WriteFile(filepath.Join(ts.Dirs.Work, "activestate.yaml"), []byte("project: "+url))) cp := ts.Spawn("invite", "qatesting+3@activestate.com") - cp.ExpectLongString("Cannot authenticate") + cp.Expect("Cannot authenticate") cp.ExpectExitCode(1) } @@ -57,7 +57,7 @@ func (suite *InviteNegativeAutomationTestSuite) TestInvite_NotAuthPrivate() { suite.Require().NoError(fileutils.WriteFile(filepath.Join(ts.Dirs.Work, "activestate.yaml"), []byte("project: "+url))) cp := ts.Spawn("invite", "qatesting+3@activestate.com") - cp.ExpectLongString("Cannot authenticate") + cp.Expect("Cannot authenticate") cp.ExpectExitCode(1) } @@ -72,25 +72,25 @@ func (suite *InviteNegativeAutomationTestSuite) TestInvite_MissingArg() { // No arguments cp := ts.Spawn("invite") - cp.ExpectLongString("The following argument is required") - cp.ExpectLongString("Name: email1") - cp.ExpectLongString("Description: Email addresses to send the invitations to") + cp.Expect("The following argument is required") + cp.Expect("Name: email1") + cp.Expect("Description: Email addresses to send the invitations to") cp.ExpectExitCode(1) // No `--role` argument cp = ts.Spawn("invite", "qatesting+3@activestate.com", "--role") - cp.ExpectLongString("Flag needs an argument: --role") + cp.Expect("Flag needs an argument: --role") cp.ExpectExitCode(1) cp = ts.Spawn("invite", "qatesting+3@activestate.com", "--organization", "ActiveState-CLI", "--role") - cp.ExpectLongString("Flag needs an argument: --role") + cp.Expect("Flag needs an argument: --role") cp.ExpectExitCode(1) // No `--organization` argument cp = ts.Spawn("invite", "qatesting+3@activestate.com", "--organization") - cp.ExpectLongString("Flag needs an argument: --organization") + cp.Expect("Flag needs an argument: --organization") cp.ExpectExitCode(1) cp = ts.Spawn("invite", "qatesting+3@activestate.com", "--role", "member", "--organization") - cp.ExpectLongString("Flag needs an argument: --organization") + cp.Expect("Flag needs an argument: --organization") cp.ExpectExitCode(1) } @@ -109,20 +109,20 @@ func (suite *InviteNegativeAutomationTestSuite) TestInvite_NonExistentArgValues_ // Non existent Role test cp := ts.Spawn("invite", "qatesting+3@activestate.com", "--role", "first") - cp.ExpectLongString("Invalid value for \"--role\" flag") - cp.ExpectLongString("Invalid role: first, should be one of: owner, member") + cp.Expect("Invalid value for \"--role\" flag") + cp.Expect("Invalid role: first, should be one of: owner, member") cp.ExpectExitCode(1) // Non existent Organization test cp = ts.Spawn("invite", "qatesting+3@activestate.com", "--organization", "noorg") - cp.ExpectLongString("Invalid value for \"--organization\" flag") - cp.ExpectLongString("Unable to find requested Organization") + cp.Expect("Invalid value for \"--organization\" flag") + cp.Expect("Unable to find requested Organization") cp.ExpectExitCode(1) // `-n` flag used cp = ts.Spawn("invite", "qatesting+3@activestate.com", "-n") cp.ExpectExitCode(1) - suite.Assert().NotContains(cp.TrimmedSnapshot(), "Invalid role") // there is an error, just not this one + suite.Assert().NotContains(cp.Output(), "Invalid role") // there is an error, just not this one } func (suite *InviteNegativeAutomationTestSuite) TestInvite_NonExistentArgValues_Private() { @@ -140,20 +140,20 @@ func (suite *InviteNegativeAutomationTestSuite) TestInvite_NonExistentArgValues_ // Non existent Role test cp := ts.Spawn("invite", "qatesting+3@activestate.com", "--role", "first") - cp.ExpectLongString("Invalid value for \"--role\" flag") - cp.ExpectLongString("Invalid role: first, should be one of: owner, member") + cp.Expect("Invalid value for \"--role\" flag") + cp.Expect("Invalid role: first, should be one of: owner, member") cp.ExpectExitCode(1) // Non existent Organization test cp = ts.Spawn("invite", "qatesting+3@activestate.com", "--organization", "noorg") - cp.ExpectLongString("Invalid value for \"--organization\" flag") - cp.ExpectLongString("Unable to find requested Organization") + cp.Expect("Invalid value for \"--organization\" flag") + cp.Expect("Unable to find requested Organization") cp.ExpectExitCode(1) // `-n` flag used cp = ts.Spawn("invite", "qatesting+3@activestate.com", "-n") cp.ExpectExitCode(1) - suite.Assert().NotContains(cp.TrimmedSnapshot(), "Invalid role") // there is an error, just not this one + suite.Assert().NotContains(cp.Output(), "Invalid role") // there is an error, just not this one } func TestInviteAutomationTestSuite(t *testing.T) { diff --git a/test/automation/learn_automation_test.go b/test/automation/learn_automation_test.go index b5e9cf2d69..af01033f43 100644 --- a/test/automation/learn_automation_test.go +++ b/test/automation/learn_automation_test.go @@ -1,10 +1,11 @@ package automation import ( + "testing" + "github.com/ActiveState/cli/internal/testhelpers/e2e" "github.com/ActiveState/cli/internal/testhelpers/tagsuite" "github.com/stretchr/testify/suite" - "testing" ) type LearnAutomationTestSuite struct { @@ -18,7 +19,7 @@ func (suite *LearnAutomationTestSuite) TestLearn_UrlProvided() { defer ts.Close() cp := ts.Spawn("learn") - cp.ExpectLongString("https://platform.activestate.com/state-tool-cheat-sheet") + cp.Expect("https://platform.activestate.com/state-tool-cheat-sheet") cp.ExpectExitCode(0) } diff --git a/test/automation/projects_automation_test.go b/test/automation/projects_automation_test.go index 0126d17f00..8ace9a7f4a 100644 --- a/test/automation/projects_automation_test.go +++ b/test/automation/projects_automation_test.go @@ -8,6 +8,7 @@ import ( "github.com/ActiveState/cli/internal/fileutils" "github.com/ActiveState/cli/internal/testhelpers/e2e" "github.com/ActiveState/cli/internal/testhelpers/tagsuite" + "github.com/ActiveState/termtest" "github.com/stretchr/testify/suite" ) @@ -22,7 +23,7 @@ func (suite *ProjectsAutomationTestSuite) TestProjects_NoActProjects() { defer ts.Close() cp := ts.Spawn("projects") - cp.ExpectLongString("You have not activated any projects yet") + cp.Expect("You have not activated any projects yet") } func (suite *ProjectsAutomationTestSuite) TestProjects_LocalChkout() { @@ -72,7 +73,7 @@ func (suite *ProjectsAutomationTestSuite) TestProjects_Remote() { ts.LoginAsPersistentUser() cp := ts.Spawn("projects", "remote") - cp.Expect("Name", time.Minute) + cp.Expect("Name", termtest.OptExpectTimeout(time.Minute)) cp.Expect("Organization") cp.Expect(e2e.PersistentUsername) cp.ExpectExitCode(0) diff --git a/test/automation/reset_automation_test.go b/test/automation/reset_automation_test.go index b91a78c2e9..67b4303596 100644 --- a/test/automation/reset_automation_test.go +++ b/test/automation/reset_automation_test.go @@ -1,12 +1,13 @@ package automation import ( + "path/filepath" + "testing" + "github.com/ActiveState/cli/internal/fileutils" "github.com/ActiveState/cli/internal/testhelpers/e2e" "github.com/ActiveState/cli/internal/testhelpers/tagsuite" "github.com/stretchr/testify/suite" - "path/filepath" - "testing" ) type ResetAutomationTestSuite struct { @@ -20,7 +21,7 @@ func (suite *ResetAutomationTestSuite) TestReset_NotInProjects() { defer ts.Close() cp := ts.Spawn("reset") - cp.ExpectLongString("you need to be in an existing project") + cp.Expect("you need to be in an existing project") cp.ExpectExitCode(1) } @@ -64,7 +65,7 @@ func (suite *ResetAutomationTestSuite) TestReset_NoAuthPrivateProject() { suite.Require().NoError(fileutils.WriteFile(filepath.Join(ts.Dirs.Work, "activestate.yaml"), []byte("project: "+url))) cp := ts.Spawn("reset") - cp.ExpectLongString("If this is a private project you may need to authenticate") + cp.Expect("If this is a private project you may need to authenticate") cp.ExpectExitCode(1) } diff --git a/test/automation/revert_automation_test.go b/test/automation/revert_automation_test.go index 6d331219d8..81d2d1f00f 100644 --- a/test/automation/revert_automation_test.go +++ b/test/automation/revert_automation_test.go @@ -1,12 +1,13 @@ package automation import ( + "path/filepath" + "testing" + "github.com/ActiveState/cli/internal/fileutils" "github.com/ActiveState/cli/internal/testhelpers/e2e" "github.com/ActiveState/cli/internal/testhelpers/tagsuite" "github.com/stretchr/testify/suite" - "path/filepath" - "testing" ) type RevertAutomationTestSuite struct { @@ -20,9 +21,9 @@ func (suite *RevertAutomationTestSuite) TestRevert_MissingArg() { defer ts.Close() cp := ts.Spawn("revert") - cp.ExpectLongString("The following argument is required") - cp.ExpectLongString("Name: commit-id") - cp.ExpectLongString("Description: The commit ID to revert to") + cp.Expect("The following argument is required") + cp.Expect("Name: commit-id") + cp.Expect("Description: The commit ID to revert to") cp.ExpectExitCode(1) } @@ -33,7 +34,7 @@ func (suite *RevertAutomationTestSuite) TestRevert_NotInProjects() { defer ts.Close() cp := ts.Spawn("revert", "111") - cp.ExpectLongString("you need to be in an existing project") + cp.Expect("you need to be in an existing project") cp.ExpectExitCode(1) } @@ -48,7 +49,7 @@ func (suite *RevertAutomationTestSuite) TestRevert_NotAuthPublic() { suite.Require().NoError(fileutils.WriteFile(filepath.Join(ts.Dirs.Work, "activestate.yaml"), []byte("project: "+url))) cp := ts.Spawn("revert", "111") - cp.ExpectLongString("You are not authenticated") + cp.Expect("You are not authenticated") cp.ExpectExitCode(1) } @@ -63,7 +64,7 @@ func (suite *RevertAutomationTestSuite) TestRevert_NotAuthPrivate() { suite.Require().NoError(fileutils.WriteFile(filepath.Join(ts.Dirs.Work, "activestate.yaml"), []byte("project: "+url))) cp := ts.Spawn("revert", "111") - cp.ExpectLongString("You are not authenticated") + cp.Expect("You are not authenticated") cp.ExpectExitCode(1) } @@ -81,8 +82,8 @@ func (suite *RevertAutomationTestSuite) TestRevert_NonexistentCommitPublic() { suite.Require().NoError(fileutils.WriteFile(filepath.Join(ts.Dirs.Work, "activestate.yaml"), []byte("project: "+url))) cp := ts.Spawn("revert", "111") - cp.ExpectLongString("Could not fetch commit details for commit with ID: 111") - cp.ExpectLongString("Could not get commit from ID: 111") + cp.Expect("Could not fetch commit details for commit with ID: 111") + cp.Expect("Could not get commit from ID: 111") cp.ExpectExitCode(1) } @@ -100,8 +101,8 @@ func (suite *RevertAutomationTestSuite) TestRevert_NonexistentCommitPrivate() { suite.Require().NoError(fileutils.WriteFile(filepath.Join(ts.Dirs.Work, "activestate.yaml"), []byte("project: "+url))) cp := ts.Spawn("revert", "111") - cp.ExpectLongString("Could not fetch commit details for commit with ID: 111") - cp.ExpectLongString("Could not get commit from ID: 111") + cp.Expect("Could not fetch commit details for commit with ID: 111") + cp.Expect("Could not get commit from ID: 111") cp.ExpectExitCode(1) } @@ -127,7 +128,7 @@ func (suite *RevertAutomationTestSuite) TestRevert_PublicProject() { // Testing if user choose YES for reset and reset have been successful cp = ts.Spawn("revert", "66e5a9ba-6762-4027-a001-6e9c54437dde") cp.SendLine("y") - cp.ExpectLongString("Successfully reverted to commit: 66e5a9ba-6762-4027-a001-6e9c54437dde") + cp.Expect("Successfully reverted to commit: 66e5a9ba-6762-4027-a001-6e9c54437dde") cp.ExpectExitCode(0) } @@ -153,7 +154,7 @@ func (suite *RevertAutomationTestSuite) TestRevert_PrivateProject() { // Testing if user choose YES for reset and reset have been successful cp = ts.Spawn("revert", "d5b7cf36-bcc2-4ba9-a910-6b8ad1098eb2") cp.SendLine("y") - cp.ExpectLongString("Successfully reverted to commit: d5b7cf36-bcc2-4ba9-a910-6b8ad1098eb2") + cp.Expect("Successfully reverted to commit: d5b7cf36-bcc2-4ba9-a910-6b8ad1098eb2") cp.ExpectExitCode(0) } diff --git a/test/automation/search_automation_test.go b/test/automation/search_automation_test.go index 7f6e7c4f54..d197ba1443 100644 --- a/test/automation/search_automation_test.go +++ b/test/automation/search_automation_test.go @@ -1,12 +1,13 @@ package automation import ( + "path/filepath" + "testing" + "github.com/ActiveState/cli/internal/fileutils" "github.com/ActiveState/cli/internal/testhelpers/e2e" "github.com/ActiveState/cli/internal/testhelpers/tagsuite" "github.com/stretchr/testify/suite" - "path/filepath" - "testing" ) type SearchAutomationTestSuite struct { @@ -20,11 +21,11 @@ func (suite *SearchAutomationTestSuite) TestSearch_NoArg() { defer ts.Close() cp := ts.Spawn("search") - cp.ExpectLongString("The following argument is required:") + cp.Expect("The following argument is required:") cp.ExpectExitCode(1) cp = ts.Spawn("search", "--language", "python") - cp.ExpectLongString("The following argument is required:") + cp.Expect("The following argument is required:") cp.ExpectExitCode(1) } @@ -35,7 +36,7 @@ func (suite *SearchAutomationTestSuite) TestSearch_NoLanguageArg() { defer ts.Close() cp := ts.Spawn("search", "--language") - cp.ExpectLongString("Flag needs an argument: --language") + cp.Expect("Flag needs an argument: --language") cp.ExpectExitCode(1) } @@ -46,7 +47,7 @@ func (suite *SearchAutomationTestSuite) TestSearch_OutProject() { defer ts.Close() cp := ts.Spawn("search", "flask") - cp.ExpectLongString("Language must be provided by flag") + cp.Expect("Language must be provided by flag") cp.ExpectExitCode(1) } diff --git a/test/integration/activate_int_test.go b/test/integration/activate_int_test.go index bea657ae2e..992f9685b2 100644 --- a/test/integration/activate_int_test.go +++ b/test/integration/activate_int_test.go @@ -12,9 +12,11 @@ import ( "testing" "time" - "github.com/ActiveState/cli/internal/rtutils" + "github.com/ActiveState/termtest" "github.com/stretchr/testify/suite" + "github.com/ActiveState/cli/internal/rtutils" + "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/exeutils" "github.com/ActiveState/cli/internal/fileutils" @@ -54,7 +56,7 @@ func (suite *ActivateIntegrationTestSuite) TestActivateWithoutRuntime() { cp := ts.Spawn("activate", "ActiveState-CLI/Python2") cp.Expect("Skipping runtime setup") cp.Expect("Activated") - cp.WaitForInput() + cp.ExpectInput() cp.SendLine("exit 123") cp.ExpectExitCode(123) @@ -84,6 +86,9 @@ func (suite *ActivateIntegrationTestSuite) addForegroundSvc(ts *e2e.Session) fun // Stop function return func() { go func() { + defer func() { + suite.Require().Nil(recover()) + }() stdout, stderr, err := exeutils.ExecSimple(ts.SvcExe, []string{"stop"}, ts.Env) suite.Require().NoError(err, "svc stop failed: %s\n%s", stdout, stderr) }() @@ -95,16 +100,8 @@ func (suite *ActivateIntegrationTestSuite) addForegroundSvc(ts *e2e.Session) fun if !errors.Is(err2, rtutils.ErrTimeout) { suite.Require().NoError(err2) } - fmt.Printf("svc did not stop in time, Stdout:\n%s\n\nStderr:\n%s", stdout.String(), stderr.String()) + suite.T().Logf("svc did not stop in time, Stdout:\n%s\n\nStderr:\n%s", stdout.String(), stderr.String()) cmd.Process.Kill() - - // If we have to kill it we can't verify the exit code as it will be non-zero due to the fact that we killed it - // thing is; due to the nature of our integration testing framework there are too many factors to consider here - // and we there's going to be cases where the stop call above didn't work due to reasons other than "it broke". - // Sadly we just can't fail on that, as we'd have periodic failures happening constantly. - // We'll address this properly with the refactor: DX-1312 - // All that said; we should still be able to verify the output, which is the real meat of this function anyway. - verifyExit = false } errMsg := fmt.Sprintf("svc foreground did not complete as expected. Stdout:\n%s\n\nStderr:\n%s", stdout.String(), stderr.String()) @@ -131,11 +128,11 @@ func (suite *ActivateIntegrationTestSuite) TestActivateUsingCommitID() { defer close() cp := ts.SpawnWithOpts( - e2e.WithArgs("activate", "ActiveState-CLI/Python3#6d9280e7-75eb-401a-9e71-0d99759fbad3", "--path", ts.Dirs.Work), + e2e.OptArgs("activate", "ActiveState-CLI/Python3#6d9280e7-75eb-401a-9e71-0d99759fbad3", "--path", ts.Dirs.Work), ) cp.Expect("Skipping runtime setup") cp.Expect("Activated") - cp.WaitForInput(10 * time.Second) + cp.ExpectInput(termtest.OptExpectTimeout(10 * time.Second)) cp.SendLine("exit") cp.ExpectExitCode(0) @@ -148,10 +145,12 @@ func (suite *ActivateIntegrationTestSuite) TestActivateNotOnPath() { close := suite.addForegroundSvc(ts) defer close() - cp := ts.SpawnWithOpts(e2e.WithArgs("activate", "activestate-cli/small-python", "--path", ts.Dirs.Work)) + cp := ts.SpawnWithOpts( + e2e.OptArgs("activate", "activestate-cli/small-python", "--path", ts.Dirs.Work), + ) cp.Expect("Skipping runtime setup") cp.Expect("Activated") - cp.WaitForInput(10 * time.Second) + cp.ExpectInput(termtest.OptExpectTimeout(10 * time.Second)) if runtime.GOOS == "windows" { cp.SendLine("doskey /macros | findstr state=") @@ -178,14 +177,14 @@ func (suite *ActivateIntegrationTestSuite) TestActivatePythonByHostOnly() { projectName := "Python-LinuxWorks" cp := ts.SpawnWithOpts( - e2e.WithArgs("activate", "cli-integration-tests/"+projectName, "--path="+ts.Dirs.Work), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("activate", "cli-integration-tests/"+projectName, "--path="+ts.Dirs.Work), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) if runtime.GOOS == "linux" { cp.Expect("Creating a Virtual Environment") - cp.Expect("Activated") - cp.WaitForInput(40 * time.Second) + cp.Expect("Activated", termtest.OptExpectTimeout(120*time.Second)) + cp.ExpectInput(termtest.OptExpectTimeout(40 * time.Second)) cp.SendLine("exit") cp.ExpectExitCode(0) } else if runtime.GOOS == "windows" { @@ -222,14 +221,14 @@ func (suite *ActivateIntegrationTestSuite) activatePython(version string, extraE namespace := "ActiveState-CLI/Python" + version cp := ts.SpawnWithOpts( - e2e.WithArgs("activate", namespace), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), - e2e.AppendEnv(extraEnv...), + e2e.OptArgs("activate", namespace), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptAppendEnv(extraEnv...), ) - cp.Expect("Activated") + cp.Expect("Activated", termtest.OptExpectTimeout(120*time.Second)) // ensure that shell is functional - cp.WaitForInput() + cp.ExpectInput() pythonExe := "python" + version @@ -248,28 +247,34 @@ func (suite *ActivateIntegrationTestSuite) activatePython(version string, extraE cp.Expect("unit and functional testing") cp.SendLine("state activate --default ActiveState-CLI/cli") - cp.ExpectLongString("Cannot make ActiveState-CLI/cli always available for use while in an activated state") + cp.Expect("Cannot make ActiveState-CLI/cli always available for use while in an activated state") cp.SendLine("state activate --default") - cp.ExpectLongString("Creating a Virtual Environment") - cp.WaitForInput(40 * time.Second) + cp.Expect("Creating a Virtual Environment") + cp.ExpectInput(termtest.OptExpectTimeout(40 * time.Second)) pythonShim := pythonExe + exeutils.Extension // test that other executables that use python work as well pipExe := "pip" + version cp.SendLine(fmt.Sprintf("%s --version", pipExe)) + + // Exit activated state + cp.SendLine("exit") + cp.ExpectExitCode(0) + pendingOutput := cp.PendingOutput() // Without waiting for exit this isn't guaranteed to have our output yet + + // Assert pip output pipVersionRe := regexp.MustCompile(`pip \d+(?:\.\d+)+ from ([^ ]+) \(python`) - cp.ExpectRe(pipVersionRe.String()) - pipVersionMatch := pipVersionRe.FindStringSubmatch(cp.TrimmedSnapshot()) - suite.Require().Len(pipVersionMatch, 2, "expected pip version to match") + pipVersionMatch := pipVersionRe.FindStringSubmatch(pendingOutput) + suite.Require().Len(pipVersionMatch, 2, "expected pip version to match, pending output: %s", pendingOutput) suite.Contains(pipVersionMatch[1], "cache", "pip loaded from activestate cache dir") executor := filepath.Join(ts.Dirs.DefaultBin, pythonShim) // check that default activation works cp = ts.SpawnCmdWithOpts( executor, - e2e.WithArgs("-c", "import sys; print(sys.copyright);"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("-c", "import sys; print(sys.copyright);"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.Expect("ActiveState Software Inc.") cp.ExpectExitCode(0) @@ -286,22 +291,22 @@ func (suite *ActivateIntegrationTestSuite) TestActivate_PythonPath() { namespace := "ActiveState-CLI/Python3" cp := ts.SpawnWithOpts( - e2e.WithArgs("activate", namespace), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("activate", namespace), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) - cp.Expect("Activated") + cp.Expect("Activated", termtest.OptExpectTimeout(120*time.Second)) // ensure that shell is functional - cp.WaitForInput() + cp.ExpectInput() // Verify that PYTHONPATH is set correctly to the installed site-packages, not a temp runtime // setup directory. if runtime.GOOS == "windows" { - cp.Send("echo %PYTHONPATH%") + cp.SendLine("echo %PYTHONPATH%") } else { - cp.Send("echo $PYTHONPATH") + cp.SendLine("echo $PYTHONPATH") } - suite.Assert().NotContains(cp.TrimmedSnapshot(), constants.LocalRuntimeTempDirectory) + suite.Assert().NotContains(cp.Output(), constants.LocalRuntimeTempDirectory) // Verify the temp runtime setup directory has been removed. runtimeFound := false entries, err := fileutils.ListDir(ts.Dirs.Cache, true) @@ -316,8 +321,8 @@ func (suite *ActivateIntegrationTestSuite) TestActivate_PythonPath() { // test that PYTHONPATH is preserved in environment (https://www.pivotaltracker.com/story/show/178458102) if runtime.GOOS == "windows" { - cp.Send("set PYTHONPATH=/custom_pythonpath") - cp.SendLine(`python3 -c 'import os; print(os.environ["PYTHONPATH"]);'`) + cp.SendLine("set PYTHONPATH=/custom_pythonpath") + cp.SendLine(`python3 -c "import os; print(os.environ['PYTHONPATH']);"`) } else { cp.SendLine(`PYTHONPATH=/custom_pythonpath python3 -c 'import os; print(os.environ["PYTHONPATH"]);'`) } @@ -341,11 +346,12 @@ func (suite *ActivateIntegrationTestSuite) TestActivate_SpaceInCacheDir() { suite.Require().NoError(err) cp := ts.SpawnWithOpts( - e2e.AppendEnv(fmt.Sprintf("%s=%s", constants.CacheEnvVarName, cacheDir)), - e2e.AppendEnv(fmt.Sprintf(`%s=""`, constants.DisableRuntime)), - e2e.WithArgs("activate", "ActiveState-CLI/Python3"), + e2e.OptAppendEnv(fmt.Sprintf("%s=%s", constants.CacheEnvVarName, cacheDir)), + e2e.OptAppendEnv(fmt.Sprintf(`%s=""`, constants.DisableRuntime)), + e2e.OptArgs("activate", "ActiveState-CLI/Python3"), ) + cp.Expect("Activated", termtest.OptExpectTimeout(120*time.Second)) cp.SendLine("python3 --version") cp.Expect("Python 3.") @@ -365,20 +371,20 @@ func (suite *ActivateIntegrationTestSuite) TestActivatePerl() { defer close() cp := ts.SpawnWithOpts( - e2e.WithArgs("activate", "ActiveState-CLI/Perl"), - e2e.AppendEnv( + e2e.OptArgs("activate", "ActiveState-CLI/Perl"), + e2e.OptAppendEnv( "ACTIVESTATE_CLI_DISABLE_RUNTIME=false", ), ) - cp.Expect("Downloading", 40*time.Second) - cp.Expect("Installing", 140*time.Second) - cp.Expect("Activated") + cp.Expect("Downloading", termtest.OptExpectTimeout(40*time.Second)) + cp.Expect("Installing", termtest.OptExpectTimeout(140*time.Second)) + cp.Expect("Activated", termtest.OptExpectTimeout(120*time.Second)) - suite.assertCompletedStatusBarReport(cp.Snapshot()) + suite.assertCompletedStatusBarReport(cp.Output()) // ensure that shell is functional - cp.WaitForInput() + cp.ExpectInput() cp.SendLine("perldoc -l DBI::DBD") // Expect the source code to be installed in the cache directory @@ -423,12 +429,12 @@ version: %s // Activate in the subdirectory c2 := ts.SpawnWithOpts( - e2e.WithArgs("activate"), - e2e.WithWorkDirectory(filepath.Join(ts.Dirs.Work, "foo", "bar", "baz")), + e2e.OptArgs("activate"), + e2e.OptWD(filepath.Join(ts.Dirs.Work, "foo", "bar", "baz")), ) c2.Expect("Activated") - c2.WaitForInput(40 * time.Second) + c2.ExpectInput(termtest.OptExpectTimeout(40 * time.Second)) c2.SendLine("exit") c2.ExpectExitCode(0) } @@ -454,13 +460,13 @@ func (suite *ActivateIntegrationTestSuite) TestActivate_NamespaceWins() { // Activate in the subdirectory c2 := ts.SpawnWithOpts( - e2e.WithArgs("activate", "ActiveState-CLI/Python2"), // activate a different namespace - e2e.WithWorkDirectory(targetPath), + e2e.OptArgs("activate", "ActiveState-CLI/Python2"), // activate a different namespace + e2e.OptWD(targetPath), ) - c2.ExpectLongString("ActiveState-CLI/Python2") + c2.Expect("ActiveState-CLI/Python2") c2.Expect("Activated") - c2.WaitForInput(40 * time.Second) + c2.ExpectInput(termtest.OptExpectTimeout(40 * time.Second)) if runtime.GOOS == "windows" { c2.SendLine("@echo %cd%") } else { @@ -481,10 +487,13 @@ func (suite *ActivateIntegrationTestSuite) TestActivate_InterruptedInstallation( close := suite.addForegroundSvc(ts) defer close() - cp := ts.Spawn("deploy", "install", "ActiveState-CLI/small-python") - // interrupting installation + cp := ts.SpawnShellWithOpts("bash", e2e.OptAppendEnv(constants.DisableRuntime+"=false")) + cp.SendLine("state deploy install ActiveState-CLI/small-python") + cp.Expect("Installing Runtime") // Ensure we don't send Ctrl+C too soon cp.SendCtrlC() - cp.ExpectNotExitCode(0) + cp.Expect("User interrupted") + cp.SendLine("exit") + cp.ExpectExit() } func (suite *ActivateIntegrationTestSuite) TestActivate_FromCache() { @@ -497,27 +506,27 @@ func (suite *ActivateIntegrationTestSuite) TestActivate_FromCache() { defer close() cp := ts.SpawnWithOpts( - e2e.WithArgs("activate", "ActiveState-CLI/small-python", "--path", ts.Dirs.Work), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("activate", "ActiveState-CLI/small-python", "--path", ts.Dirs.Work), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.Expect("Downloading") cp.Expect("Installing") - cp.Expect("Activated") + cp.Expect("Activated", termtest.OptExpectTimeout(120*time.Second)) - suite.assertCompletedStatusBarReport(cp.Snapshot()) + suite.assertCompletedStatusBarReport(cp.Output()) cp.SendLine("exit") cp.ExpectExitCode(0) // next activation is cached cp = ts.SpawnWithOpts( - e2e.WithArgs("activate", "ActiveState-CLI/small-python", "--path", ts.Dirs.Work), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("activate", "ActiveState-CLI/small-python", "--path", ts.Dirs.Work), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) - cp.WaitForInput() + cp.ExpectInput() cp.SendLine("exit") cp.ExpectExitCode(0) - suite.NotContains(cp.TrimmedSnapshot(), "Downloading") + suite.NotContains(cp.Output(), "Downloading") } func TestActivateIntegrationTestSuite(t *testing.T) { @@ -538,7 +547,7 @@ func (suite *ActivateIntegrationTestSuite) TestActivateCommitURL() { // Ensure we have the most up to date version of the project before activating cp := ts.Spawn("activate") - cp.Expect("Activated") + cp.Expect("Activated", termtest.OptExpectTimeout(120*time.Second)) cp.SendLine("exit") cp.ExpectExitCode(0) } @@ -553,15 +562,15 @@ func (suite *ActivateIntegrationTestSuite) TestActivate_AlreadyActive() { namespace := "ActiveState-CLI/Python3" - cp := ts.SpawnWithOpts(e2e.WithArgs("activate", namespace)) + cp := ts.SpawnWithOpts(e2e.OptArgs("activate", namespace)) cp.Expect("Skipping runtime setup") cp.Expect("Activated") // ensure that shell is functional - cp.WaitForInput() + cp.ExpectInput() cp.SendLine("state activate") cp.Expect("Your project is already active") - cp.WaitForInput() + cp.ExpectInput() } func (suite *ActivateIntegrationTestSuite) TestActivate_AlreadyActive_SameNamespace() { @@ -574,15 +583,15 @@ func (suite *ActivateIntegrationTestSuite) TestActivate_AlreadyActive_SameNamesp namespace := "ActiveState-CLI/Python3" - cp := ts.SpawnWithOpts(e2e.WithArgs("activate", namespace)) + cp := ts.SpawnWithOpts(e2e.OptArgs("activate", namespace)) cp.Expect("Skipping runtime setup") cp.Expect("Activated") // ensure that shell is functional - cp.WaitForInput() + cp.ExpectInput() cp.SendLine(fmt.Sprintf("state activate %s", namespace)) cp.Expect("Your project is already active") - cp.WaitForInput() + cp.ExpectInput() } func (suite *ActivateIntegrationTestSuite) TestActivate_AlreadyActive_DifferentNamespace() { @@ -595,15 +604,15 @@ func (suite *ActivateIntegrationTestSuite) TestActivate_AlreadyActive_DifferentN namespace := "ActiveState-CLI/Python3" - cp := ts.SpawnWithOpts(e2e.WithArgs("activate", namespace)) + cp := ts.SpawnWithOpts(e2e.OptArgs("activate", namespace)) cp.Expect("Skipping runtime setup") cp.Expect("Activated") // ensure that shell is functional - cp.WaitForInput() + cp.ExpectInput() cp.SendLine(fmt.Sprintf("state activate %s", "ActiveState-CLI/Perl-5.32")) cp.Expect("You cannot activate a new project when you are already in an activated state") - cp.WaitForInput() + cp.ExpectInput() } func (suite *ActivateIntegrationTestSuite) TestActivateBranch() { @@ -617,7 +626,7 @@ func (suite *ActivateIntegrationTestSuite) TestActivateBranch() { namespace := "ActiveState-CLI/Branches" cp := ts.SpawnWithOpts( - e2e.WithArgs("activate", namespace, "--branch", "firstbranch"), + e2e.OptArgs("activate", namespace, "--branch", "firstbranch"), ) cp.Expect("Skipping runtime setup") cp.Expect("Activated") @@ -635,7 +644,7 @@ func (suite *ActivateIntegrationTestSuite) TestActivateBranchNonExistant() { namespace := "ActiveState-CLI/Branches" - cp := ts.SpawnWithOpts(e2e.WithArgs("activate", namespace, "--branch", "does-not-exist")) + cp := ts.SpawnWithOpts(e2e.OptArgs("activate", namespace, "--branch", "does-not-exist")) cp.Expect("has no branch") } @@ -651,11 +660,11 @@ func (suite *ActivateIntegrationTestSuite) TestActivateArtifactsCached() { namespace := "ActiveState-CLI/Python3" cp := ts.SpawnWithOpts( - e2e.WithArgs("activate", namespace), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("activate", namespace), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) - cp.Expect("Activated") + cp.Expect("Activated", termtest.OptExpectTimeout(120*time.Second)) cp.SendLine("exit") cp.ExpectExitCode(0) @@ -674,18 +683,20 @@ func (suite *ActivateIntegrationTestSuite) TestActivateArtifactsCached() { suite.NoError(err) for _, entry := range files { if entry.IsDir() && entry.RelativePath() != constants.ArtifactMetaDir { - fmt.Println("removing " + entry.Path()) os.RemoveAll(entry.Path()) } } cp = ts.SpawnWithOpts( - e2e.WithArgs("activate", namespace), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false", "VERBOSE=true"), + e2e.OptArgs("activate", namespace), + e2e.OptAppendEnv( + "ACTIVESTATE_CLI_DISABLE_RUNTIME=false", + "VERBOSE=true", // Necessary to assert "Fetched cached artifact" + ), ) cp.Expect("Fetched cached artifact") - cp.Expect("Activated") + cp.Expect("Activated", termtest.OptExpectTimeout(120*time.Second)) cp.SendLine("exit") cp.ExpectExitCode(0) } diff --git a/test/integration/analytics_int_test.go b/test/integration/analytics_int_test.go index c1d98373d0..6b24829581 100644 --- a/test/integration/analytics_int_test.go +++ b/test/integration/analytics_int_test.go @@ -10,6 +10,11 @@ import ( "testing" "time" + "github.com/ActiveState/termtest" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + "github.com/thoas/go-funk" + "github.com/ActiveState/cli/internal/analytics/client/sync/reporters" anaConst "github.com/ActiveState/cli/internal/analytics/constants" "github.com/ActiveState/cli/internal/condition" @@ -19,10 +24,6 @@ import ( "github.com/ActiveState/cli/internal/testhelpers/e2e" "github.com/ActiveState/cli/internal/testhelpers/tagsuite" "github.com/ActiveState/cli/pkg/platform/runtime/target" - "github.com/ActiveState/termtest" - "github.com/stretchr/testify/require" - "github.com/stretchr/testify/suite" - "github.com/thoas/go-funk" ) type AnalyticsIntegrationTestSuite struct { @@ -61,23 +62,23 @@ func (suite *AnalyticsIntegrationTestSuite) TestHeartbeats() { // Produce Activate Heartbeats - var cp *termtest.ConsoleProcess + var cp *e2e.SpawnedCmd if runtime.GOOS == "windows" { cp = ts.SpawnCmdWithOpts("cmd.exe", - e2e.WithArgs("/k", "state", "activate"), - e2e.WithWorkDirectory(ts.Dirs.Work), - e2e.AppendEnv(env...), + e2e.OptArgs("/k", "state", "activate"), + e2e.OptWD(ts.Dirs.Work), + e2e.OptAppendEnv(env...), ) } else { - cp = ts.SpawnWithOpts(e2e.WithArgs("activate"), - e2e.WithWorkDirectory(ts.Dirs.Work), - e2e.AppendEnv(env...), + cp = ts.SpawnWithOpts(e2e.OptArgs("activate"), + e2e.OptWD(ts.Dirs.Work), + e2e.OptAppendEnv(env...), ) } cp.Expect("Creating a Virtual Environment") - cp.Expect("Activated") - cp.WaitForInput(120 * time.Second) + cp.Expect("Activated", termtest.OptExpectTimeout(120*time.Second)) + cp.ExpectInput(termtest.OptExpectTimeout(120 * time.Second)) time.Sleep(time.Second) // Ensure state-svc has time to report events @@ -94,12 +95,12 @@ func (suite *AnalyticsIntegrationTestSuite) TestHeartbeats() { // Runtime:start events suite.assertNEvents(events, 1, anaConst.CatRuntimeDebug, anaConst.ActRuntimeStart, anaConst.SrcStateTool, fmt.Sprintf("output:\n%s\n%s", - cp.Snapshot(), ts.DebugLogs())) + cp.Output(), ts.DebugLogsDump())) // Runtime:success events suite.assertNEvents(events, 1, anaConst.CatRuntimeDebug, anaConst.ActRuntimeSuccess, anaConst.SrcStateTool, fmt.Sprintf("output:\n%s\n%s", - cp.Snapshot(), ts.DebugLogs())) + cp.Output(), ts.DebugLogsDump())) // Runtime-use:attempts events attemptInitialCount := countEvents(events, anaConst.CatRuntimeUsage, anaConst.ActRuntimeAttempt, anaConst.SrcStateTool) @@ -125,7 +126,7 @@ func (suite *AnalyticsIntegrationTestSuite) TestHeartbeats() { // Runtime-use:heartbeat events - should now be at least +1 because we waited suite.assertGtEvents(events, heartbeatInitialCount, anaConst.CatRuntimeUsage, anaConst.ActRuntimeHeartbeat, anaConst.SrcStateTool, fmt.Sprintf("output:\n%s\n%s", - cp.Snapshot(), ts.DebugLogs())) + cp.Output(), ts.DebugLogsDump())) /* EXECUTOR TESTS */ @@ -172,8 +173,7 @@ func (suite *AnalyticsIntegrationTestSuite) TestHeartbeats() { cp.SendLine("exit") } suite.Require().NoError(rtutils.Timeout(func() error { - _, err := cp.ExpectExitCode(0) - return err + return cp.ExpectExitCode(0) }, 5*time.Second), ts.DebugMessage("Timed out waiting for exit code")) time.Sleep(sleepTime) // give time to let rtwatcher detect process has exited @@ -233,9 +233,9 @@ func (suite *AnalyticsIntegrationTestSuite) TestExecEvents() { /* EXEC TESTS */ cp := ts.SpawnWithOpts( - e2e.WithArgs("exec", "--", "python3", "-c", fmt.Sprintf("import time; time.sleep(%f); print('DONE')", sleepTime.Seconds())), - e2e.WithWorkDirectory(ts.Dirs.Work), - e2e.AppendEnv(env...), + e2e.OptArgs("exec", "--", "python3", "-c", fmt.Sprintf("import time; time.sleep(%f); print('DONE')", sleepTime.Seconds())), + e2e.OptWD(ts.Dirs.Work), + e2e.OptAppendEnv(env...), ) cp.Expect("DONE") @@ -398,14 +398,14 @@ scripts: ts.PrepareCommitIdFile("9090c128-e948-4388-8f7f-96e2c1e00d98") cp := ts.SpawnWithOpts( - e2e.WithArgs("activate", "ActiveState-CLI/Alternate-Python"), - e2e.WithWorkDirectory(ts.Dirs.Work), + e2e.OptArgs("activate", "ActiveState-CLI/Alternate-Python"), + e2e.OptWD(ts.Dirs.Work), ) cp.Expect("Creating a Virtual Environment") cp.Expect("Skipping runtime setup") cp.Expect("Activated") - cp.WaitForInput(10 * time.Second) + cp.ExpectInput(termtest.OptExpectTimeout(10 * time.Second)) cp = ts.Spawn("run", "pip") cp.Wait() @@ -501,7 +501,7 @@ func (suite *AnalyticsIntegrationTestSuite) TestInputError() { suite.assertNEvents(events, 1, anaConst.CatDebug, anaConst.ActCommandInputError, anaConst.SrcStateTool, fmt.Sprintf("output:\n%s\n%s", - cp.Snapshot(), ts.DebugLogs())) + cp.Output(), ts.DebugLogsDump())) for _, event := range events { if event.Category == anaConst.CatDebug && event.Action == anaConst.ActCommandInputError { @@ -519,14 +519,14 @@ func (suite *AnalyticsIntegrationTestSuite) TestAttempts() { ts.PrepareProject("ActiveState-CLI/test", "9090c128-e948-4388-8f7f-96e2c1e00d98") cp := ts.SpawnWithOpts( - e2e.WithArgs("activate", "ActiveState-CLI/Alternate-Python"), - e2e.AppendEnv(constants.DisableRuntime+"=false"), - e2e.WithWorkDirectory(ts.Dirs.Work), + e2e.OptArgs("activate", "ActiveState-CLI/Alternate-Python"), + e2e.OptAppendEnv(constants.DisableRuntime+"=false"), + e2e.OptWD(ts.Dirs.Work), ) cp.Expect("Creating a Virtual Environment") - cp.Expect("Activated") - cp.WaitForInput(120 * time.Second) + cp.Expect("Activated", termtest.OptExpectTimeout(120*time.Second)) + cp.ExpectInput(termtest.OptExpectTimeout(120 * time.Second)) cp.SendLine("python3 --version") cp.Expect("Python 3.") @@ -563,13 +563,13 @@ func (suite *AnalyticsIntegrationTestSuite) TestHeapEvents() { ts.LoginAsPersistentUser() - cp := ts.SpawnWithOpts(e2e.WithArgs("activate", "ActiveState-CLI/Alternate-Python"), - e2e.WithWorkDirectory(ts.Dirs.Work), + cp := ts.SpawnWithOpts(e2e.OptArgs("activate", "ActiveState-CLI/Alternate-Python"), + e2e.OptWD(ts.Dirs.Work), ) cp.Expect("Creating a Virtual Environment") - cp.Expect("Activated") - cp.WaitForInput(120 * time.Second) + cp.Expect("Activated", termtest.OptExpectTimeout(120*time.Second)) + cp.ExpectInput(termtest.OptExpectTimeout(120 * time.Second)) time.Sleep(time.Second) // Ensure state-svc has time to report events @@ -603,15 +603,15 @@ func (suite *AnalyticsIntegrationTestSuite) TestConfigEvents() { ts := e2e.New(suite.T(), true) defer ts.Close() - cp := ts.SpawnWithOpts(e2e.WithArgs("config", "set", "optin.unstable", "false"), - e2e.WithWorkDirectory(ts.Dirs.Work), + cp := ts.SpawnWithOpts(e2e.OptArgs("config", "set", "optin.unstable", "false"), + e2e.OptWD(ts.Dirs.Work), ) cp.Expect("Successfully set config key") time.Sleep(time.Second) // Ensure state-svc has time to report events - cp = ts.SpawnWithOpts(e2e.WithArgs("config", "set", "optin.unstable", "true"), - e2e.WithWorkDirectory(ts.Dirs.Work), + cp = ts.SpawnWithOpts(e2e.OptArgs("config", "set", "optin.unstable", "true"), + e2e.OptWD(ts.Dirs.Work), ) cp.Expect("Successfully set config key") @@ -656,7 +656,7 @@ func (suite *AnalyticsIntegrationTestSuite) TestCIAndInteractiveDimensions() { if !interactive { args = append(args, "--non-interactive") } - cp := ts.SpawnWithOpts(e2e.WithArgs(args...)) + cp := ts.SpawnWithOpts(e2e.OptArgs(args...)) cp.Expect("ActiveState CLI") cp.ExpectExitCode(0) diff --git a/test/integration/api_int_test.go b/test/integration/api_int_test.go index 1d3049342b..50ab0a988d 100644 --- a/test/integration/api_int_test.go +++ b/test/integration/api_int_test.go @@ -20,8 +20,8 @@ func (suite *ApiIntegrationTestSuite) TestRequestHeaders() { defer ts.Close() cp := ts.SpawnWithOpts( - e2e.WithArgs("checkout", "ActiveState-CLI/Python3", "."), - e2e.AppendEnv(constants.PlatformApiPrintRequestsEnvVarName+"=true", "VERBOSE=true"), + e2e.OptArgs("checkout", "ActiveState-CLI/Python3", "."), + e2e.OptAppendEnv(constants.PlatformApiPrintRequestsEnvVarName+"=true", "VERBOSE=true"), ) // e.g. User-Agent: state/0.38.0-SHA0deadbeef0; release (Windows; 10.0.22621; x86_64) cp.ExpectRe(`User-Agent: state/(\d+\.?)+-SHA[[:xdigit:]]+; \S+ \([^;]+; [^;]+; [^)]+\)`) diff --git a/test/integration/auth_int_test.go b/test/integration/auth_int_test.go index 1244c71580..06c957efe3 100644 --- a/test/integration/auth_int_test.go +++ b/test/integration/auth_int_test.go @@ -6,6 +6,7 @@ import ( "testing" "time" + "github.com/ActiveState/termtest" "github.com/google/uuid" "github.com/stretchr/testify/suite" @@ -47,11 +48,11 @@ func (suite *AuthIntegrationTestSuite) TestAuthToken() { defer ts.Close() cp := ts.Spawn(tagsuite.Auth, "--token", e2e.PersistentToken, "-n") - cp.Expect("logged in", 40*time.Second) + cp.Expect("logged in", termtest.OptExpectTimeout(40*time.Second)) cp.ExpectExitCode(0) cp = ts.Spawn(tagsuite.Auth, "--non-interactive") - cp.Expect("logged in", 40*time.Second) + cp.Expect("logged in", termtest.OptExpectTimeout(40*time.Second)) cp.ExpectExitCode(0) ts.LogoutUser() @@ -61,10 +62,10 @@ func (suite *AuthIntegrationTestSuite) TestAuthToken() { func (suite *AuthIntegrationTestSuite) interactiveLogin(ts *e2e.Session, username, password string) { cp := ts.Spawn(tagsuite.Auth, "--prompt") cp.Expect("username:") - cp.Send(username) + cp.SendLine(username) cp.Expect("password:") - cp.Send(password) - cp.Expect("logged in", 40*time.Second) + cp.SendLine(password) + cp.Expect("logged in") cp.ExpectExitCode(0) // still logged in? @@ -75,7 +76,7 @@ func (suite *AuthIntegrationTestSuite) interactiveLogin(ts *e2e.Session, usernam func (suite *AuthIntegrationTestSuite) loginFlags(ts *e2e.Session, username string) { cp := ts.Spawn(tagsuite.Auth, "--username", username, "--password", "bad-password") - cp.ExpectLongString("You are not authorized, did you provide valid login credentials?") + cp.Expect("You are not authorized, did you provide valid login credentials?") cp.ExpectExitCode(1) } @@ -110,7 +111,7 @@ func (suite *AuthIntegrationTestSuite) authOutput(method string) { cp := ts.Spawn(tagsuite.Auth, "--output", method) cp.Expect("false}") cp.ExpectExitCode(0) - suite.Equal(fmt.Sprintf("%s", string(expected)), cp.TrimmedSnapshot()) + suite.Contains(cp.Output(), fmt.Sprintf("%s", string(expected))) } func (suite *AuthIntegrationTestSuite) TestAuth_JsonOutput() { diff --git a/test/integration/branch_int_test.go b/test/integration/branch_int_test.go index e981809526..1b74f0f56d 100644 --- a/test/integration/branch_int_test.go +++ b/test/integration/branch_int_test.go @@ -2,11 +2,14 @@ package integration import ( "testing" + "time" - "github.com/ActiveState/cli/internal/testhelpers/e2e" - "github.com/ActiveState/cli/internal/testhelpers/tagsuite" + "github.com/ActiveState/termtest" "github.com/google/uuid" "github.com/stretchr/testify/suite" + + "github.com/ActiveState/cli/internal/testhelpers/e2e" + "github.com/ActiveState/cli/internal/testhelpers/tagsuite" ) type BranchIntegrationTestSuite struct { @@ -20,15 +23,9 @@ func (suite *BranchIntegrationTestSuite) TestBranch_List() { ts.PrepareProject("ActiveState-CLI/Branches", "") - cp := ts.Spawn("branch") - expected := `main (Current) - ├─ firstbranch - │ └─ firstbranchchild - │ └─ childoffirstbranchchild - ├─ secondbranch - └─ thirdbranch -` - cp.ExpectLongString(expected) + cp := ts.SpawnWithOpts(e2e.OptArgs("branch"), e2e.OptTermTest(termtest.OptVerboseLogging())) + // Sometimes there's a space before the line break, unsure exactly why, but hence the regex + cp.ExpectRe(`main \(Current\)\s?\n ├─ firstbranch\s?\n │ └─ firstbranchchild\s?\n │ └─ childoffirstbranchchild\s?\n ├─ secondbranch\s?\n └─ thirdbranch`, termtest.OptExpectTimeout(5*time.Second)) cp.ExpectExitCode(0) } @@ -43,7 +40,7 @@ func (suite *BranchIntegrationTestSuite) TestBranch_Add() { ts.LoginAsPersistentUser() cp := ts.Spawn("pull") - cp.ExpectLongString("Your project in the activestate.yaml has been updated") + cp.Expect("Your project in the activestate.yaml has been updated") cp.ExpectExitCode(0) branchName, err := uuid.NewRandom() diff --git a/test/integration/bundle_int_test.go b/test/integration/bundle_int_test.go index 94ac41189c..88f4a40d96 100644 --- a/test/integration/bundle_int_test.go +++ b/test/integration/bundle_int_test.go @@ -5,6 +5,7 @@ import ( "testing" "time" + "github.com/ActiveState/termtest" "github.com/stretchr/testify/suite" "github.com/ActiveState/cli/internal/testhelpers/e2e" @@ -79,7 +80,7 @@ func (suite *BundleIntegrationTestSuite) TestBundle_project_invalid() { defer ts.Close() cp := ts.Spawn("bundles", "--namespace", "junk/junk") - cp.ExpectLongString("The requested project junk/junk could not be found") + cp.Expect("The requested project junk/junk could not be found") cp.ExpectExitCode(1) } @@ -127,7 +128,7 @@ func (suite *BundleIntegrationTestSuite) TestBundle_searchWithExactTermWrongTerm suite.PrepareActiveStateYAML(ts) cp := ts.Spawn("bundles", "search", "xxxUtilitiesxxx", "--exact-term") - cp.ExpectLongString("No bundles in our catalog match") + cp.Expect("No bundles in our catalog match") cp.ExpectExitCode(1) } @@ -149,7 +150,7 @@ func (suite *BundleIntegrationTestSuite) TestBundle_searchWithWrongLang() { suite.PrepareActiveStateYAML(ts) cp := ts.Spawn("bundles", "search", "Utilities", "--language=python") - cp.ExpectLongString("No bundles in our catalog match") + cp.Expect("No bundles in our catalog match") cp.ExpectExitCode(1) } @@ -181,13 +182,13 @@ func (suite *BundleIntegrationTestSuite) TestBundle_headless_operation() { suite.Run("install non-existing", func() { cp := ts.Spawn("bundles", "install", "non-existing") cp.Expect("No results found for search term") - cp.ExpectLongString(`Run "state search non-existing" to find alternatives`) + cp.Expect(`Run "state search non-existing" to find alternatives`) cp.Wait() }) suite.Run("install", func() { cp := ts.Spawn("bundles", "install", "Utilities") - cp.ExpectRe("successfully installed", 45*time.Second) + cp.ExpectRe("successfully installed", termtest.OptExpectTimeout(45*time.Second)) cp.Wait() }) @@ -201,7 +202,7 @@ func (suite *BundleIntegrationTestSuite) TestBundle_headless_operation() { suite.Run("uninstall", func() { cp := ts.Spawn("bundles", "uninstall", "Utilities") - cp.ExpectRe("Bundle uninstalled", 30*time.Second) + cp.ExpectRe("Bundle uninstalled", termtest.OptExpectTimeout(30*time.Second)) cp.Wait() }) } @@ -221,16 +222,16 @@ func (suite *BundleIntegrationTestSuite) TestJSON() { AssertValidJSON(suite.T(), cp) cp = ts.SpawnWithOpts( - e2e.WithArgs("bundles", "install", "Testing", "--output", "json"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("bundles", "install", "Testing", "--output", "json"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.Expect(`"name":"Testing"`) cp.ExpectExitCode(0) AssertValidJSON(suite.T(), cp) cp = ts.SpawnWithOpts( - e2e.WithArgs("bundles", "uninstall", "Testing", "-o", "editor"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("bundles", "uninstall", "Testing", "-o", "editor"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.Expect(`"name":"Testing"`) cp.ExpectExitCode(0) diff --git a/test/integration/checkout_int_test.go b/test/integration/checkout_int_test.go index eaf23b1b6e..9c35f2b52f 100644 --- a/test/integration/checkout_int_test.go +++ b/test/integration/checkout_int_test.go @@ -7,6 +7,10 @@ import ( "runtime" "strings" "testing" + "time" + + "github.com/ActiveState/termtest" + "github.com/stretchr/testify/suite" "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/exeutils" @@ -16,7 +20,6 @@ import ( "github.com/ActiveState/cli/pkg/platform/runtime/setup" "github.com/ActiveState/cli/pkg/platform/runtime/target" "github.com/ActiveState/cli/pkg/projectfile" - "github.com/stretchr/testify/suite" ) type CheckoutIntegrationTestSuite struct { @@ -31,10 +34,10 @@ func (suite *CheckoutIntegrationTestSuite) TestCheckout() { // Checkout and verify. cp := ts.SpawnWithOpts( - e2e.WithArgs("checkout", "ActiveState-CLI/Python-3.9", "."), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("checkout", "ActiveState-CLI/Python-3.9", "."), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) - cp.Expect("Checked out project") + cp.Expect("Checked out project", termtest.OptExpectTimeout(120*time.Second)) suite.Require().True(fileutils.DirExists(ts.Dirs.Work), "state checkout should have created "+ts.Dirs.Work) suite.Require().True(fileutils.FileExists(filepath.Join(ts.Dirs.Work, constants.ConfigFileName)), "ActiveState-CLI/Python3 was not checked out properly") @@ -63,11 +66,14 @@ func (suite *CheckoutIntegrationTestSuite) TestCheckout() { suite.Require().NoError(os.Remove(filepath.Join(ts.Dirs.Work, constants.ConfigFileName))) // Ensure we can do another checkout cp = ts.SpawnWithOpts( - e2e.WithArgs("checkout", "ActiveState-CLI/Python-3.9", "."), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false", "VERBOSE=true"), + e2e.OptArgs("checkout", "ActiveState-CLI/Python-3.9", "."), + e2e.OptAppendEnv( + "ACTIVESTATE_CLI_DISABLE_RUNTIME=false", + "VERBOSE=true", // Necessary to assert "Fetched cached artifact" + ), ) - cp.Expect("Fetched cached artifact") // Comes from log, which is why we're using VERBOSE=true - cp.Expect("Checked out project") + cp.Expect("Fetched cached artifact", termtest.OptExpectTimeout(120*time.Second)) // Comes from log, which is why we're using VERBOSE=true + cp.Expect("Checked out project", termtest.OptExpectTimeout(120*time.Second)) cp.ExpectExitCode(0) }) } @@ -86,8 +92,8 @@ func (suite *CheckoutIntegrationTestSuite) TestCheckoutNonEmptyDir() { // Checkout and verify. cp := ts.SpawnWithOpts( - e2e.WithArgs("checkout", "ActiveState-CLI/Python3", tmpdir), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=true"), + e2e.OptArgs("checkout", "ActiveState-CLI/Python3", tmpdir), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=true"), ) cp.Expect("already a project checked out at") cp.ExpectExitCode(1) @@ -95,8 +101,8 @@ func (suite *CheckoutIntegrationTestSuite) TestCheckoutNonEmptyDir() { // remove file suite.Require().NoError(os.Remove(filepath.Join(tmpdir, constants.ConfigFileName))) cp = ts.SpawnWithOpts( - e2e.WithArgs("checkout", "ActiveState-CLI/Python3", tmpdir), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=true"), + e2e.OptArgs("checkout", "ActiveState-CLI/Python3", tmpdir), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=true"), ) cp.Expect("Checked out project") cp.ExpectExitCode(0) @@ -114,8 +120,8 @@ func (suite *CheckoutIntegrationTestSuite) TestCheckoutMultiDir() { for x, dir := range dirs { cp := ts.SpawnWithOpts( - e2e.WithArgs("checkout", "ActiveState-CLI/Python3", "."), - e2e.WithWorkDirectory(dir), + e2e.OptArgs("checkout", "ActiveState-CLI/Python3", "."), + e2e.OptWD(dir), ) cp.Expect("Skipping runtime setup") cp.Expect("Checked out") @@ -131,7 +137,7 @@ func (suite *CheckoutIntegrationTestSuite) TestCheckoutWithFlags() { defer ts.Close() // Test checking out to current working directory. - cp := ts.SpawnWithOpts(e2e.WithArgs("checkout", "ActiveState-CLI/Python3", ".")) + cp := ts.SpawnWithOpts(e2e.OptArgs("checkout", "ActiveState-CLI/Python3", ".")) cp.Expect("Skipping runtime setup") cp.Expect("Checked out") cp.Expect(ts.Dirs.Work) @@ -139,7 +145,7 @@ func (suite *CheckoutIntegrationTestSuite) TestCheckoutWithFlags() { // Test checkout out to a generic path. python3Dir := filepath.Join(ts.Dirs.Work, "MyPython3") - cp = ts.SpawnWithOpts(e2e.WithArgs("checkout", "ActiveState-CLI/Python3#6d9280e7-75eb-401a-9e71-0d99759fbad3", python3Dir)) + cp = ts.SpawnWithOpts(e2e.OptArgs("checkout", "ActiveState-CLI/Python3#6d9280e7-75eb-401a-9e71-0d99759fbad3", python3Dir)) cp.Expect("Skipping runtime setup") cp.Expect("Checked out") cp.ExpectExitCode(0) @@ -151,8 +157,8 @@ func (suite *CheckoutIntegrationTestSuite) TestCheckoutWithFlags() { // Test --branch mismatch in non-checked-out project. branchPath := filepath.Join(ts.Dirs.Base, "branch") - cp = ts.SpawnWithOpts(e2e.WithArgs("checkout", "ActiveState-CLI/Python-3.9", branchPath, "--branch", "doesNotExist")) - cp.ExpectLongString("This project has no branch with label matching doesNotExist") + cp = ts.SpawnWithOpts(e2e.OptArgs("checkout", "ActiveState-CLI/Python-3.9", branchPath, "--branch", "doesNotExist")) + cp.Expect("This project has no branch with label matching doesNotExist") cp.ExpectExitCode(1) } @@ -169,10 +175,10 @@ func (suite *CheckoutIntegrationTestSuite) TestCheckoutCustomRTPath() { // Checkout and verify. cp := ts.SpawnWithOpts( - e2e.WithArgs("checkout", "ActiveState-CLI/Python3", fmt.Sprintf("--runtime-path=%s", customRTPath)), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("checkout", "ActiveState-CLI/Python3", fmt.Sprintf("--runtime-path=%s", customRTPath)), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) - cp.Expect("Checked out project") + cp.Expect("Checked out project", termtest.OptExpectTimeout(120*time.Second)) pythonExe := filepath.Join(setup.ExecDir(customRTPath), "python3"+exeutils.Extension) suite.Require().True(fileutils.DirExists(customRTPath)) @@ -185,9 +191,9 @@ func (suite *CheckoutIntegrationTestSuite) TestCheckoutCustomRTPath() { // Verify that state exec works with custom cache. cp = ts.SpawnWithOpts( - e2e.WithArgs("exec", "python3", "--", "-c", "import sys;print(sys.executable)"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), - e2e.WithWorkDirectory(filepath.Join(ts.Dirs.Work, "Python3")), + e2e.OptArgs("exec", "python3", "--", "-c", "import sys;print(sys.executable)"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptWD(filepath.Join(ts.Dirs.Work, "Python3")), ) if runtime.GOOS == "windows" { customRTPath, err = fileutils.GetLongPathName(customRTPath) @@ -203,11 +209,11 @@ func (suite *CheckoutIntegrationTestSuite) TestCheckoutAlreadyCheckedOut() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.SpawnWithOpts(e2e.WithArgs("checkout", "ActiveState-CLI/small-python")) + cp := ts.SpawnWithOpts(e2e.OptArgs("checkout", "ActiveState-CLI/small-python")) cp.Expect("Checked out project") cp.ExpectExitCode(0) - cp = ts.SpawnWithOpts(e2e.WithArgs("checkout", "ActiveState-CLI/small-python")) + cp = ts.SpawnWithOpts(e2e.OptArgs("checkout", "ActiveState-CLI/small-python")) cp.Expect("already a project checked out at") cp.ExpectNotExitCode(0) } @@ -217,12 +223,9 @@ func (suite *CheckoutIntegrationTestSuite) TestJSON() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.SpawnWithOpts(e2e.WithArgs("checkout", "ActiveState-CLI/small-python", "-o", "json")) - cp.Expect(`"namespace":`) - cp.Expect(`"path":`) - cp.Expect(`"executables":`) + cp := ts.SpawnWithOpts(e2e.OptArgs("checkout", "ActiveState-CLI/small-python", "-o", "json")) cp.ExpectExitCode(0) - //AssertValidJSON(suite.T(), cp) // cannot assert here due to "Skipping runtime setup" notice + AssertValidJSON(suite.T(), cp) } func (suite *CheckoutIntegrationTestSuite) TestCheckoutCaseInsensitive() { @@ -231,7 +234,7 @@ func (suite *CheckoutIntegrationTestSuite) TestCheckoutCaseInsensitive() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.SpawnWithOpts(e2e.WithArgs("checkout", "ACTIVESTATE-CLI/SMALL-PYTHON")) + cp := ts.SpawnWithOpts(e2e.OptArgs("checkout", "ACTIVESTATE-CLI/SMALL-PYTHON")) cp.Expect("Skipping runtime setup") cp.Expect("Checked out project") cp.ExpectExitCode(0) diff --git a/test/integration/commit_int_test.go b/test/integration/commit_int_test.go index b71c2c9375..8595b8bf6a 100644 --- a/test/integration/commit_int_test.go +++ b/test/integration/commit_int_test.go @@ -4,6 +4,7 @@ import ( "bytes" "path/filepath" "testing" + "time" "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/fileutils" @@ -11,6 +12,7 @@ import ( "github.com/ActiveState/cli/internal/testhelpers/tagsuite" "github.com/ActiveState/cli/pkg/platform/runtime/buildscript" "github.com/ActiveState/cli/pkg/project" + "github.com/ActiveState/termtest" "github.com/stretchr/testify/suite" ) @@ -26,14 +28,14 @@ func (suite *CommitIntegrationTestSuite) TestCommitManualBuildScriptMod() { ts.LoginAsPersistentUser() cp := ts.SpawnWithOpts( - e2e.WithArgs( + e2e.OptArgs( "checkout", "ActiveState-CLI/Commit-Test-A#7a1b416e-c17f-4d4a-9e27-cbad9e8f5655", ".", ), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) - cp.Expect("Checked out") + cp.Expect("Checked out", termtest.OptExpectTimeout(120*time.Second)) cp.ExpectExitCode(0) proj, err := project.FromPath(ts.Dirs.Work) diff --git a/test/integration/condition_int_test.go b/test/integration/condition_int_test.go index 42b9a72f88..b134c8f059 100644 --- a/test/integration/condition_int_test.go +++ b/test/integration/condition_int_test.go @@ -23,8 +23,7 @@ func (suite *ConditionIntegrationTestSuite) TestCondition() { suite.PrepareActiveStateYAML(ts) cp := ts.SpawnWithOpts( - e2e.WithArgs("run", "test"), - e2e.AppendEnv("VERBOSE=true"), + e2e.OptArgs("run", "test"), ) cp.Expect(`projectNameValue`) cp.Expect(`projectOwnerValue`) @@ -36,21 +35,21 @@ func (suite *ConditionIntegrationTestSuite) TestCondition() { cp.ExpectExitCode(0) cp = ts.SpawnWithOpts( - e2e.WithArgs("activate"), + e2e.OptArgs("activate"), ) cp.Expect(`Activation Event Ran`) - cp.WaitForInput() + cp.ExpectInput() cp.SendLine("exit") cp.ExpectExitCode(0) cp = ts.SpawnWithOpts( - e2e.WithArgs("run", "complex-true"), + e2e.OptArgs("run", "complex-true"), ) cp.Expect(`I exist`) cp.ExpectExitCode(0) cp = ts.SpawnWithOpts( - e2e.WithArgs("run", "complex-false"), + e2e.OptArgs("run", "complex-false"), ) cp.ExpectExitCode(1) } @@ -63,17 +62,17 @@ func (suite *ConditionIntegrationTestSuite) TestMixin() { suite.PrepareActiveStateYAML(ts) cp := ts.SpawnWithOpts( - e2e.WithArgs("run", "MixinUser"), + e2e.OptArgs("run", "MixinUser"), ) cp.ExpectExitCode(0) - suite.Assert().NotContains(cp.TrimmedSnapshot(), "authenticated: yes", "expected not to be authenticated, output was:\n%s.", cp.Snapshot()) - suite.Assert().NotContains(cp.TrimmedSnapshot(), e2e.PersistentUsername, "expected not to be authenticated, output was:\n%s", cp.Snapshot()) + suite.Assert().NotContains(cp.Output(), "authenticated: yes", "expected not to be authenticated, output was:\n%s.", cp.Output()) + suite.Assert().NotContains(cp.Output(), e2e.PersistentUsername, "expected not to be authenticated, output was:\n%s", cp.Output()) ts.LoginAsPersistentUser() defer ts.LogoutUser() cp = ts.SpawnWithOpts( - e2e.WithArgs("run", "MixinUser"), + e2e.OptArgs("run", "MixinUser"), ) cp.Expect("authenticated: yes") cp.Expect(e2e.PersistentUsername) @@ -88,7 +87,7 @@ func (suite *ConditionIntegrationTestSuite) TestConditionOSName() { suite.PrepareActiveStateYAML(ts) cp := ts.SpawnWithOpts( - e2e.WithArgs("run", "OSName"), + e2e.OptArgs("run", "OSName"), ) if runtime.GOOS == "windows" { cp.Expect(`using-windows`) @@ -108,7 +107,7 @@ func (suite *ConditionIntegrationTestSuite) TestConditionSyntaxError() { suite.PrepareActiveStateYAMLWithSyntaxError(ts) cp := ts.SpawnWithOpts( - e2e.WithArgs("run", "test"), + e2e.OptArgs("run", "test"), ) cp.Expect(`not defined`) // for now we aren't passing the error up the chain, so invalid syntax will lead to empty result cp.ExpectExitCode(1) diff --git a/test/integration/cve_int_test.go b/test/integration/cve_int_test.go index 3fcdc53bc8..6b05d49da3 100644 --- a/test/integration/cve_int_test.go +++ b/test/integration/cve_int_test.go @@ -23,7 +23,8 @@ func (suite *CveIntegrationTestSuite) TestCveSummary() { ts.PrepareProject("ActiveState-CLI/VulnerablePython-3.7", "0b87e7a4-dc62-46fd-825b-9c35a53fe0a2") cp := ts.Spawn("cve") - cp.ExpectLongString("Operating on project ActiveState-CLI/VulnerablePython-3.7") + cp.Expect("Operating on project") + cp.Expect("ActiveState-CLI/VulnerablePython-3.7") cp.Expect("VulnerablePython-3.7") cp.Expect("0b87e7a4-dc62-46fd-825b-9c35a53fe0a2") @@ -93,7 +94,7 @@ func (suite *CveIntegrationTestSuite) TestCveInvalidProject() { ts.LoginAsPersistentUser() cp := ts.Spawn("cve", "report", "invalid/invalid") - cp.ExpectLongString("Found no project with specified organization and name") + cp.Expect("Found no project with specified organization and name") cp.ExpectNotExitCode(0) } diff --git a/test/integration/deploy_int_test.go b/test/integration/deploy_int_test.go index 02ba91d0e2..5e7ad02d14 100644 --- a/test/integration/deploy_int_test.go +++ b/test/integration/deploy_int_test.go @@ -34,35 +34,35 @@ func init() { } func (suite *DeployIntegrationTestSuite) deploy(ts *e2e.Session, prj string, targetPath string, targetID string) { - var cp *termtest.ConsoleProcess + var cp *e2e.SpawnedCmd switch runtime.GOOS { case "windows": cp = ts.SpawnWithOpts( - e2e.WithArgs("deploy", prj, "--path", targetPath), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("deploy", prj, "--path", targetPath), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) case "darwin": // On MacOS the command is the same as Linux, however some binaries // already exist at /usr/local/bin so we use the --force flag cp = ts.SpawnWithOpts( - e2e.WithArgs("deploy", prj, "--path", targetPath, "--force"), - e2e.AppendEnv("SHELL=bash"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("deploy", prj, "--path", targetPath, "--force"), + e2e.OptAppendEnv("SHELL=bash"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) default: cp = ts.SpawnWithOpts( - e2e.WithArgs("deploy", prj, "--path", targetPath), - e2e.AppendEnv("SHELL=bash"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("deploy", prj, "--path", targetPath), + e2e.OptAppendEnv("SHELL=bash"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) } - cp.Expect("Installing", 40*time.Second) - cp.Expect("Configuring", 40*time.Second) + cp.Expect("Installing", termtest.OptExpectTimeout(40*time.Second)) + cp.Expect("Configuring", termtest.OptExpectTimeout(40*time.Second)) if runtime.GOOS != "windows" { - cp.Expect("Symlinking", 30*time.Second) + cp.Expect("Symlinking", termtest.OptExpectTimeout(30*time.Second)) } - cp.Expect("Deployment Information", 60*time.Second) + cp.Expect("Deployment Information", termtest.OptExpectTimeout(60*time.Second)) cp.Expect(targetID) // expect bin dir if runtime.GOOS == "windows" { cp.Expect("log out") @@ -94,19 +94,19 @@ func (suite *DeployIntegrationTestSuite) TestDeployPerl() { suite.checkSymlink("perl", ts.Dirs.Bin, targetID.String()) - var cp *termtest.ConsoleProcess + var cp *e2e.SpawnedCmd if runtime.GOOS == "windows" { cp = ts.SpawnCmdWithOpts( "cmd.exe", - e2e.WithArgs("/k", filepath.Join(targetPath, "bin", "shell.bat")), - e2e.AppendEnv("PATHEXT=.COM;.EXE;.BAT;.LNK", "SHELL="), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("/k", filepath.Join(targetPath, "bin", "shell.bat")), + e2e.OptAppendEnv("PATHEXT=.COM;.EXE;.BAT;.LNK", "SHELL="), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) } else { cp = ts.SpawnCmdWithOpts( "/bin/bash", - e2e.AppendEnv("PROMPT_COMMAND="), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false")) + e2e.OptAppendEnv("PROMPT_COMMAND="), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false")) cp.SendLine(fmt.Sprintf("source %s\n", filepath.Join(targetPath, "bin", "shell.sh"))) } @@ -170,19 +170,19 @@ func (suite *DeployIntegrationTestSuite) TestDeployPython() { suite.checkSymlink("python3", ts.Dirs.Bin, targetID.String()) - var cp *termtest.ConsoleProcess + var cp *e2e.SpawnedCmd if runtime.GOOS == "windows" { cp = ts.SpawnCmdWithOpts( "cmd.exe", - e2e.WithArgs("/k", filepath.Join(targetPath, "bin", "shell.bat")), - e2e.AppendEnv("PATHEXT=.COM;.EXE;.BAT;.LNK", "SHELL="), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("/k", filepath.Join(targetPath, "bin", "shell.bat")), + e2e.OptAppendEnv("PATHEXT=.COM;.EXE;.BAT;.LNK", "SHELL="), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) } else { cp = ts.SpawnCmdWithOpts( "/bin/bash", - e2e.AppendEnv("PROMPT_COMMAND="), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false")) + e2e.OptAppendEnv("PROMPT_COMMAND="), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false")) cp.SendLine(fmt.Sprintf("source %s\n", filepath.Join(targetPath, "bin", "shell.sh"))) } @@ -243,13 +243,13 @@ func (suite *DeployIntegrationTestSuite) TestDeployInstall() { func (suite *DeployIntegrationTestSuite) InstallAndAssert(ts *e2e.Session, targetPath string) { cp := ts.SpawnWithOpts( - e2e.WithArgs("deploy", "install", "ActiveState-CLI/Python3", "--path", targetPath), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("deploy", "install", "ActiveState-CLI/Python3", "--path", targetPath), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.Expect("Installing Runtime") - cp.Expect("Installing", 120*time.Second) - cp.Expect("Installation completed", 120*time.Second) + cp.Expect("Installing", termtest.OptExpectTimeout(120*time.Second)) + cp.Expect("Installation completed", termtest.OptExpectTimeout(120*time.Second)) cp.ExpectExitCode(0) } @@ -271,8 +271,8 @@ func (suite *DeployIntegrationTestSuite) TestDeployConfigure() { // Install step is required cp := ts.SpawnWithOpts( - e2e.WithArgs("deploy", "configure", "ActiveState-CLI/Python3", "--path", targetPath), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("deploy", "configure", "ActiveState-CLI/Python3", "--path", targetPath), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.Expect("need to run the install step") cp.ExpectExitCode(1) @@ -280,27 +280,27 @@ func (suite *DeployIntegrationTestSuite) TestDeployConfigure() { if runtime.GOOS != "windows" { cp = ts.SpawnWithOpts( - e2e.WithArgs("deploy", "configure", "ActiveState-CLI/Python3", "--path", targetPath), - e2e.AppendEnv("SHELL=bash"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("deploy", "configure", "ActiveState-CLI/Python3", "--path", targetPath), + e2e.OptAppendEnv("SHELL=bash"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) } else { cp = ts.SpawnWithOpts( - e2e.WithArgs("deploy", "configure", "ActiveState-CLI/Python3", "--path", targetPath), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("deploy", "configure", "ActiveState-CLI/Python3", "--path", targetPath), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) } - cp.Expect("Configuring shell", 60*time.Second) + cp.Expect("Configuring shell", termtest.OptExpectTimeout(60*time.Second)) cp.ExpectExitCode(0) suite.AssertConfig(ts, targetID.String()) if runtime.GOOS == "windows" { cp = ts.SpawnWithOpts( - e2e.WithArgs("deploy", "configure", "ActiveState-CLI/Python3", "--path", targetPath, "--user"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("deploy", "configure", "ActiveState-CLI/Python3", "--path", targetPath, "--user"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) - cp.Expect("Configuring shell", 60*time.Second) + cp.Expect("Configuring shell", termtest.OptExpectTimeout(60*time.Second)) cp.ExpectExitCode(0) out, err := exec.Command("reg", "query", `HKCU\Environment`, "/v", "Path").Output() @@ -363,8 +363,8 @@ func (suite *DeployIntegrationTestSuite) TestDeploySymlink() { // Install step is required cp := ts.SpawnWithOpts( - e2e.WithArgs("deploy", "symlink", "ActiveState-CLI/Python3", "--path", targetPath), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("deploy", "symlink", "ActiveState-CLI/Python3", "--path", targetPath), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.Expect("need to run the install step") cp.ExpectExitCode(1) @@ -372,13 +372,13 @@ func (suite *DeployIntegrationTestSuite) TestDeploySymlink() { if runtime.GOOS != "darwin" { cp = ts.SpawnWithOpts( - e2e.WithArgs("deploy", "symlink", "ActiveState-CLI/Python3", "--path", targetPath), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("deploy", "symlink", "ActiveState-CLI/Python3", "--path", targetPath), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) } else { cp = ts.SpawnWithOpts( - e2e.WithArgs("deploy", "symlink", "ActiveState-CLI/Python3", "--path", targetPath, "--force"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("deploy", "symlink", "ActiveState-CLI/Python3", "--path", targetPath, "--force"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) } @@ -404,16 +404,16 @@ func (suite *DeployIntegrationTestSuite) TestDeployReport() { // Install step is required cp := ts.SpawnWithOpts( - e2e.WithArgs("deploy", "report", "ActiveState-CLI/Python3", "--path", targetPath), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("deploy", "report", "ActiveState-CLI/Python3", "--path", targetPath), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.Expect("need to run the install step") cp.ExpectExitCode(1) suite.InstallAndAssert(ts, targetPath) cp = ts.SpawnWithOpts( - e2e.WithArgs("deploy", "report", "ActiveState-CLI/Python3", "--path", targetPath), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("deploy", "report", "ActiveState-CLI/Python3", "--path", targetPath), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.Expect("Deployment Information") cp.Expect(targetID.String()) // expect bin dir @@ -442,9 +442,9 @@ func (suite *DeployIntegrationTestSuite) TestDeployTwice() { pathDir := fileutils.TempDirUnsafe() defer os.RemoveAll(pathDir) cp := ts.SpawnWithOpts( - e2e.WithArgs("deploy", "symlink", "ActiveState-CLI/Python3", "--path", targetPath), - e2e.AppendEnv(fmt.Sprintf("PATH=%s", pathDir)), // Avoid conflicts - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("deploy", "symlink", "ActiveState-CLI/Python3", "--path", targetPath), + e2e.OptAppendEnv(fmt.Sprintf("PATH=%s", pathDir)), // Avoid conflicts + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.ExpectExitCode(0) @@ -455,9 +455,9 @@ func (suite *DeployIntegrationTestSuite) TestDeployTwice() { // Running deploy a second time should not cause any errors (cache is properly picked up) cpx := ts.SpawnWithOpts( - e2e.WithArgs("deploy", "symlink", "ActiveState-CLI/Python3", "--path", targetPath), - e2e.AppendEnv(fmt.Sprintf("PATH=%s", pathDir)), // Avoid conflicts - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("deploy", "symlink", "ActiveState-CLI/Python3", "--path", targetPath), + e2e.OptAppendEnv(fmt.Sprintf("PATH=%s", pathDir)), // Avoid conflicts + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cpx.ExpectExitCode(0) } @@ -482,8 +482,8 @@ func (suite *DeployIntegrationTestSuite) TestDeployUninstall() { // Uninstall deployed runtime. cp := ts.SpawnWithOpts( - e2e.WithArgs("deploy", "uninstall", "--path", filepath.Join(ts.Dirs.Work, "target")), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("deploy", "uninstall", "--path", filepath.Join(ts.Dirs.Work, "target")), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.Expect("Uninstall Deployed Runtime") cp.Expect("Successful") @@ -493,8 +493,8 @@ func (suite *DeployIntegrationTestSuite) TestDeployUninstall() { // Trying to uninstall again should fail cp = ts.SpawnWithOpts( - e2e.WithArgs("deploy", "uninstall", "--path", filepath.Join(ts.Dirs.Work, "target")), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("deploy", "uninstall", "--path", filepath.Join(ts.Dirs.Work, "target")), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.Expect("no deployed runtime") cp.ExpectExitCode(1) @@ -502,8 +502,8 @@ func (suite *DeployIntegrationTestSuite) TestDeployUninstall() { // Trying to uninstall in a non-deployment directory should fail. cp = ts.SpawnWithOpts( - e2e.WithArgs("deploy", "uninstall"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("deploy", "uninstall"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.Expect("no deployed runtime") cp.ExpectExitCode(1) @@ -511,8 +511,8 @@ func (suite *DeployIntegrationTestSuite) TestDeployUninstall() { // Trying to uninstall in a non-deployment directory should not delete that directory. cp = ts.SpawnWithOpts( - e2e.WithArgs("deploy", "uninstall", "--path", ts.Dirs.Work), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("deploy", "uninstall", "--path", ts.Dirs.Work), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.Expect("no deployed runtime") cp.ExpectExitCode(1) diff --git a/test/integration/e2eissues_int_test.go b/test/integration/e2eissues_int_test.go index 9e0dc6597d..f7956c6b02 100644 --- a/test/integration/e2eissues_int_test.go +++ b/test/integration/e2eissues_int_test.go @@ -6,6 +6,8 @@ import ( "testing" "time" + "github.com/ActiveState/termtest" + "github.com/ActiveState/cli/internal/fileutils" "github.com/ActiveState/cli/internal/testhelpers/e2e" ) @@ -16,8 +18,6 @@ The intend is to collect e2e bugs here so that we can test that they are fixed o */ func TestMultipleSends(t *testing.T) { - t.Skip("") - if runtime.GOOS != "windows" { t.Skip("This test is only relevant on Windows") } @@ -31,18 +31,18 @@ func TestMultipleSends(t *testing.T) { set /p "prompt1=Prompt 1: " echo "Prompt 1: %prompt1%" set /p "prompt2=Prompt 2: " -echo "Prompt 2: %prompt1%" +echo "Prompt 2: %prompt2%" `)) if err != nil { t.Fatal(err) } - tp := ts.SpawnCmd(promptFile) - tp.Expect("Prompt 1: ", 5*time.Second) - tp.Send("Answer 1") - tp.Expect("Prompt 1: Answer 1", 5*time.Second) - tp.Expect("Prompt 2: ", 5*time.Second) - tp.Send("Answer 2") - tp.Expect("Prompt 2: Answer 2", 5*time.Second) - tp.ExpectExitCode(0, 5*time.Second) + tp := ts.SpawnCmdWithOpts(promptFile, e2e.OptTermTest(termtest.OptDefaultTimeout(5*time.Second))) + tp.Expect("Prompt 1:") + tp.SendLine("Answer 1") + tp.Expect("Prompt 1: Answer 1") + tp.Expect("Prompt 2:") + tp.SendLine("Answer 2") + tp.Expect("Prompt 2: Answer 2") + tp.ExpectExitCode(0) } diff --git a/test/integration/edit_int_test.go b/test/integration/edit_int_test.go index b4dbdb890f..683ad7ad6d 100644 --- a/test/integration/edit_int_test.go +++ b/test/integration/edit_int_test.go @@ -22,7 +22,7 @@ type EditIntegrationTestSuite struct { tagsuite.Suite } -func (suite *EditIntegrationTestSuite) setup() (*e2e.Session, e2e.SpawnOptions) { +func (suite *EditIntegrationTestSuite) setup() (*e2e.Session, e2e.SpawnOptSetter) { ts := e2e.New(suite.T(), false) root := environment.GetRootPathUnsafe() @@ -48,13 +48,13 @@ scripts: } cp := ts.SpawnCmdWithOpts( "go", - e2e.WithArgs("build", "-o", "editor"+extension, target), - e2e.WithWorkDirectory(editorScriptDir), + e2e.OptArgs("build", "-o", "editor"+extension, target), + e2e.OptWD(editorScriptDir), ) cp.ExpectExitCode(0) suite.Require().FileExists(filepath.Join(editorScriptDir, "editor"+extension)) - return ts, e2e.AppendEnv(fmt.Sprintf("EDITOR=%s", filepath.Join(editorScriptDir, "editor"+extension))) + return ts, e2e.OptAppendEnv(fmt.Sprintf("EDITOR=%s", filepath.Join(editorScriptDir, "editor"+extension))) } func (suite *EditIntegrationTestSuite) TearDownTest() { @@ -65,10 +65,10 @@ func (suite *EditIntegrationTestSuite) TestEdit() { suite.OnlyRunForTags(tagsuite.Edit) ts, env := suite.setup() defer ts.Close() - cp := ts.SpawnWithOpts(e2e.WithArgs("scripts", "edit", "test-script"), env) + cp := ts.SpawnWithOpts(e2e.OptArgs("scripts", "edit", "test-script"), env) cp.Expect("Watching file changes") cp.Expect("Script changes detected") - cp.Send("Y") + cp.SendLine("Y") cp.ExpectExitCode(0) } @@ -79,9 +79,9 @@ func (suite *EditIntegrationTestSuite) TestEdit_NonInteractive() { } ts, env := suite.setup() defer ts.Close() - extraEnv := e2e.AppendEnv("ACTIVESTATE_NONINTERACTIVE=true") + extraEnv := e2e.OptAppendEnv("ACTIVESTATE_NONINTERACTIVE=true") - cp := ts.SpawnWithOpts(e2e.WithArgs("scripts", "edit", "test-script"), env, extraEnv) + cp := ts.SpawnWithOpts(e2e.OptArgs("scripts", "edit", "test-script"), env, extraEnv) cp.Expect("Watching file changes") // Can't consistently get this line detected on CI cp.Expect("Script changes detected") @@ -99,11 +99,12 @@ func (suite *EditIntegrationTestSuite) TestEdit_UpdateCorrectPlatform() { ts, env := suite.setup() defer ts.Close() cp := ts.SpawnWithOpts( - e2e.WithArgs("scripts", "edit", "test-script"), - e2e.WithWorkDirectory(ts.Dirs.Work), + e2e.OptArgs("scripts", "edit", "test-script"), + e2e.OptWD(ts.Dirs.Work), env, ) - cp.Send("Y") + cp.Expect("(Y/n)") + cp.SendLine("Y") cp.ExpectExitCode(0) time.Sleep(time.Second * 2) // let CI env catch up @@ -115,7 +116,7 @@ func (suite *EditIntegrationTestSuite) TestEdit_UpdateCorrectPlatform() { suite.Require().NotNil(s, "test-script should not be empty") v, err := s.Value() suite.Require().NoError(err) - suite.Contains(v, "more info!", "Output of edit command:\n%s", cp.Snapshot()) + suite.Contains(v, "more info!", "Output of edit command:\n%s", cp.Output()) } func TestEditIntegrationTestSuite(t *testing.T) { diff --git a/test/integration/events_int_test.go b/test/integration/events_int_test.go index 4bc3557379..febab9708a 100644 --- a/test/integration/events_int_test.go +++ b/test/integration/events_int_test.go @@ -45,21 +45,21 @@ events: ts.PrepareCommitIdFile("fbc613d6-b0b1-4f84-b26e-4aa5869c4e54") cp := ts.Spawn("activate") - cp.Send("") + cp.SendEnter() cp.Expect("before-script") cp.Expect("First activate event") cp.Expect("Activate event") - cp.WaitForInput() + cp.ExpectInput() cp.SendLine("exit") cp.Expect("after-script") cp.ExpectExitCode(0) cp = ts.Spawn("activate") cp.Expect("Activate event") - cp.WaitForInput() + cp.ExpectInput() cp.SendLine("exit") cp.ExpectExitCode(0) - output := cp.TrimmedSnapshot() + output := cp.Output() if strings.Contains(output, "First activate event") { suite.T().Fatal("Output from second activate event should not contain first-activate output") } diff --git a/test/integration/exec_int_test.go b/test/integration/exec_int_test.go index aa38e7f159..23c422ae4f 100644 --- a/test/integration/exec_int_test.go +++ b/test/integration/exec_int_test.go @@ -45,10 +45,10 @@ func (suite *ExecIntegrationTestSuite) TestExec_Environment() { suite.Require().NoError(err) cp := ts.SpawnWithOpts( - e2e.WithArgs("exec", testScript), + e2e.OptArgs("exec", testScript), ) cp.ExpectExitCode(0) - output := cp.Snapshot() + output := cp.Output() suite.Contains(output, ts.Dirs.Bin, "PATH was not updated to contain cache directory, original PATH:", os.Getenv("PATH")) } @@ -74,7 +74,7 @@ func (suite *ExecIntegrationTestSuite) TestExec_ExitCode() { suite.Require().NoError(err) cp := ts.SpawnWithOpts( - e2e.WithArgs("exec", "--", testScript), + e2e.OptArgs("exec", "--", testScript), ) cp.ExpectExitCode(42) } @@ -119,7 +119,7 @@ echo "Number of arguments: $#" } cp := ts.SpawnWithOpts( - e2e.WithArgs("exec", "--", fmt.Sprintf("%s", testScript), args[0], args[1], args[2]), + e2e.OptArgs("exec", "--", fmt.Sprintf("%s", testScript), args[0], args[1], args[2]), ) cp.Expect(args[0]) cp.Expect(args[1]) @@ -156,7 +156,7 @@ echo "Hello $name!" suite.Require().NoError(err) cp := ts.SpawnWithOpts( - e2e.WithArgs("exec", "--", fmt.Sprintf("%s", testScript)), + e2e.OptArgs("exec", "--", fmt.Sprintf("%s", testScript)), ) cp.SendLine("ActiveState") cp.Expect("Hello ActiveState!") @@ -174,22 +174,22 @@ func (suite *ExecIntegrationTestSuite) TestExecWithPath() { pythonDir := filepath.Join(ts.Dirs.Work, "MyPython3") - cp := ts.SpawnWithOpts(e2e.WithArgs("checkout", "ActiveState-CLI/Python-3.9", pythonDir)) + cp := ts.SpawnWithOpts(e2e.OptArgs("checkout", "ActiveState-CLI/Python-3.9", pythonDir)) cp.Expect("Skipping runtime setup") cp.Expect("Checked out project") cp.ExpectExitCode(0) cp = ts.SpawnWithOpts( - e2e.WithArgs("exec", "--path", pythonDir, "which", "python3"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("exec", "--path", pythonDir, "which", "python3"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) - cp.ExpectLongString("Operating on project ActiveState-CLI/Python-3.9") + cp.Expect("Operating on project ActiveState-CLI/Python-3.9") cp.ExpectRe(regexp.MustCompile("cache/[0-9A-Fa-f]+/usr/bin/python3").String()) cp.ExpectExitCode(0) cp = ts.SpawnWithOpts( - e2e.WithArgs("exec", "echo", "python3", "--path", pythonDir, "--", "--path", "doesNotExist", "--", "extra"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("exec", "echo", "python3", "--path", pythonDir, "--", "--path", "doesNotExist", "--", "extra"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.Expect("python3 --path doesNotExist -- extra") cp.ExpectExitCode(0) diff --git a/test/integration/executor_int_test.go b/test/integration/executor_int_test.go index 7307cc30bd..8bb6aa9a09 100644 --- a/test/integration/executor_int_test.go +++ b/test/integration/executor_int_test.go @@ -4,12 +4,15 @@ import ( "os" "path/filepath" "testing" + "time" + + "github.com/ActiveState/termtest" + "github.com/stretchr/testify/suite" "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/exeutils" "github.com/ActiveState/cli/internal/testhelpers/e2e" "github.com/ActiveState/cli/internal/testhelpers/tagsuite" - "github.com/stretchr/testify/suite" ) type ExecutorIntegrationTestSuite struct { @@ -27,17 +30,17 @@ func (suite *ExecutorIntegrationTestSuite) TestExecutorForwards() { defer ts.Close() cp := ts.SpawnWithOpts( - e2e.WithArgs("checkout", "ActiveState-CLI/Python3"), + e2e.OptArgs("checkout", "ActiveState-CLI/Python3"), ) cp.Expect("Checked out project") cp.ExpectExitCode(0) cp = ts.SpawnWithOpts( - e2e.WithArgs("shell", "ActiveState-CLI/Python3"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("shell", "ActiveState-CLI/Python3"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) - cp.Expect("Activated") - cp.WaitForInput() + cp.Expect("Activated", termtest.OptExpectTimeout(120*time.Second)) + cp.ExpectInput() cp.SendLine("python3 -c \"import sys; print(sys.copyright)\"") cp.Expect("ActiveState Software Inc.") @@ -54,17 +57,17 @@ func (suite *ExecutorIntegrationTestSuite) TestExecutorExitCode() { defer ts.Close() cp := ts.SpawnWithOpts( - e2e.WithArgs("checkout", "ActiveState-CLI/Python3"), + e2e.OptArgs("checkout", "ActiveState-CLI/Python3"), ) cp.Expect("Checked out project") cp.ExpectExitCode(0) cp = ts.SpawnWithOpts( - e2e.WithArgs("shell", "ActiveState-CLI/Python3"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("shell", "ActiveState-CLI/Python3"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) - cp.Expect("Activated") - cp.WaitForInput() + cp.Expect("Activated", termtest.OptExpectTimeout(120*time.Second)) + cp.ExpectInput() cp.SendLine("python3 -c \"exit(42)\"") diff --git a/test/integration/export_int_test.go b/test/integration/export_int_test.go index 605ba85e4f..853fa2726a 100644 --- a/test/integration/export_int_test.go +++ b/test/integration/export_int_test.go @@ -6,6 +6,7 @@ import ( "github.com/ActiveState/cli/internal/testhelpers/e2e" "github.com/ActiveState/cli/internal/testhelpers/tagsuite" + "github.com/ActiveState/termtest" "github.com/stretchr/testify/suite" ) @@ -74,7 +75,7 @@ func (suite *ExportIntegrationTestSuite) TestExport_Config() { ts.PrepareProject("cli-integration-tests/Export", "") cp := ts.Spawn("export", "config") cp.Expect(`dir: `) - cp.ExpectLongString(ts.Dirs.Config, time.Second) + cp.Expect(ts.Dirs.Config, termtest.OptExpectTimeout(time.Second)) cp.ExpectExitCode(0) } @@ -85,13 +86,13 @@ func (suite *ExportIntegrationTestSuite) TestExport_Env() { ts.PrepareProject("ActiveState-CLI/Export", "5397f645-da8a-4591-b106-9d7fa99545fe") cp := ts.SpawnWithOpts( - e2e.WithArgs("export", "env"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("export", "env"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.Expect(`PATH: `) cp.ExpectExitCode(0) - suite.Assert().NotContains(cp.TrimmedSnapshot(), "ACTIVESTATE_ACTIVATED") + suite.Assert().NotContains(cp.Output(), "ACTIVESTATE_ACTIVATED") } func (suite *ExportIntegrationTestSuite) TestJSON() { @@ -104,14 +105,15 @@ func (suite *ExportIntegrationTestSuite) TestJSON() { cp.ExpectExitCode(0) AssertValidJSON(suite.T(), cp) - cp = ts.Spawn("checkout", "ActiveState-CLI/small-python", ".") - cp.Expect("Skipping runtime setup") - cp.Expect("Checked out") - cp.ExpectExitCode(0) + cp = ts.SpawnWithOpts( + e2e.OptArgs("checkout", "ActiveState-CLI/small-python", "."), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + ) + cp.ExpectExitCode(0, termtest.OptExpectTimeout(120*time.Second)) cp = ts.SpawnWithOpts( - e2e.WithArgs("export", "env", "-o", "json"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("export", "env", "-o", "json"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.ExpectExitCode(0) AssertValidJSON(suite.T(), cp) @@ -126,7 +128,7 @@ func (suite *ExportIntegrationTestSuite) TestJSON() { cp.Expect(`{`) cp.Expect(`}`) cp.ExpectExitCode(0) - //AssertValidJSON(suite.T(), cp) // recipe is too large to fit in terminal snapshot + // AssertValidJSON(suite.T(), cp) // recipe is too large to fit in terminal snapshot } func TestExportIntegrationTestSuite(t *testing.T) { diff --git a/test/integration/fork_int_test.go b/test/integration/fork_int_test.go index 2f2e242a58..caed6c377b 100644 --- a/test/integration/fork_int_test.go +++ b/test/integration/fork_int_test.go @@ -4,6 +4,7 @@ import ( "testing" "time" + "github.com/ActiveState/termtest" "github.com/stretchr/testify/suite" "github.com/ActiveState/cli/internal/testhelpers/e2e" @@ -44,8 +45,8 @@ func (suite *ForkIntegrationTestSuite) TestFork_FailNameExists() { defer suite.cleanup(ts) ts.LoginAsPersistentUser() - cp := ts.SpawnWithOpts(e2e.WithArgs("fork", "ActiveState-CLI/Python3", "--org", e2e.PersistentUsername)) - cp.Expect("You already have a project with the name 'Python3'", 30*time.Second) + cp := ts.SpawnWithOpts(e2e.OptArgs("fork", "ActiveState-CLI/Python3", "--org", e2e.PersistentUsername)) + cp.Expect("You already have a project with the name 'Python3'", termtest.OptExpectTimeout(30*time.Second)) cp.ExpectNotExitCode(0) } diff --git a/test/integration/hello_int_example_test.go b/test/integration/hello_int_example_test.go index b69435c625..3953b4a0aa 100644 --- a/test/integration/hello_int_example_test.go +++ b/test/integration/hello_int_example_test.go @@ -22,25 +22,20 @@ func (suite *HelloIntegrationTestSuite) TestHello() { cp.Expect("Checked out project") cp.ExpectExitCode(0) - cp = ts.Spawn("_hello") - cp.Expect("Hello, Friend!") - cp.ExpectExitCode(0) - cp = ts.Spawn("_hello", "Person") cp.Expect("Hello, Person!") cp.ExpectExitCode(0) cp = ts.Spawn("_hello", "") - cp.Expect("Cannot say hello") - cp.Expect("No name provided") + cp.Expect("Cannot say hello because no name was provided") cp.ExpectNotExitCode(0) - cp = ts.Spawn("_hello", "--extra") + cp = ts.Spawn("_hello", "Person", "--extra") cp.Expect("Project: ActiveState-CLI/small-python") cp.Expect("Current commit message:") cp.ExpectExitCode(0) - cp = ts.Spawn("_hello", "--echo", "example") + cp = ts.Spawn("_hello", "Person", "--echo", "example") cp.Expect("Echoing: example") cp.ExpectExitCode(0) } diff --git a/test/integration/help_int_test.go b/test/integration/help_int_test.go index 4fba9cabe7..da5e85be71 100644 --- a/test/integration/help_int_test.go +++ b/test/integration/help_int_test.go @@ -5,6 +5,7 @@ import ( "github.com/ActiveState/cli/internal/testhelpers/e2e" "github.com/ActiveState/cli/internal/testhelpers/tagsuite" + "github.com/ActiveState/termtest" "github.com/stretchr/testify/suite" ) @@ -21,7 +22,7 @@ func (suite *HelpIntegrationTestSuite) TestCommandListing() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.Spawn("--help") + cp := ts.SpawnWithOpts(e2e.OptArgs("--help"), e2e.OptTermTest(termtest.OptCols(80))) cp.Expect("Usage:") cp.Expect("Environment Setup:") cp.Expect("Environment Usage:") diff --git a/test/integration/history_int_test.go b/test/integration/history_int_test.go index 8e53fe38d2..dcf1d96a79 100644 --- a/test/integration/history_int_test.go +++ b/test/integration/history_int_test.go @@ -26,20 +26,21 @@ func (suite *HistoryIntegrationTestSuite) TestHistory_History() { cp.ExpectExitCode(0) cp = ts.SpawnWithOpts( - e2e.WithArgs("history"), - e2e.WithWorkDirectory(filepath.Join(ts.Dirs.Work, "History")), + e2e.OptArgs("history"), + e2e.OptWD(filepath.Join(ts.Dirs.Work, "History")), ) - cp.ExpectLongString("Operating on project ActiveState-CLI/History") + cp.Expect("Operating on project") + cp.Expect("ActiveState-CLI/History") cp.Expect("Commit") cp.Expect("Author") cp.Expect("Date") cp.Expect("Message") - cp.ExpectLongString("• requests (2.26.0 → 2.7.0)") - cp.ExpectLongString("• autopip (1.6.0 → Auto)") + cp.Expect("• requests (2.26.0 → 2.7.0)") + cp.Expect("• autopip (1.6.0 → Auto)") cp.Expect("+ autopip 1.6.0") cp.Expect("- convertdate") cp.Expect(`+ Platform`) - suite.Assert().NotContains(cp.TrimmedSnapshot(), "StructuredChanges") + suite.Assert().NotContains(cp.Output(), "StructuredChanges") cp.ExpectExitCode(0) } @@ -61,7 +62,7 @@ func (suite *HistoryIntegrationTestSuite) TestJSON() { cp.Expect(`"version_constraints_old":`) cp.Expect(`"version_constraints_new":`) cp.ExpectExitCode(0) - //AssertValidJSON(suite.T(), cp) // list is too large to fit in terminal snapshot + // AssertValidJSON(suite.T(), cp) // list is too large to fit in terminal snapshot } func TestHistoryIntegrationTestSuite(t *testing.T) { diff --git a/test/integration/import_int_test.go b/test/integration/import_int_test.go index 02efd57973..df3ab98706 100644 --- a/test/integration/import_int_test.go +++ b/test/integration/import_int_test.go @@ -39,7 +39,8 @@ func (suite *ImportIntegrationTestSuite) TestImport_headless() { suite.Require().NoError(err) cp = ts.Spawn("import", importPath) - cp.ExpectLongString("Operating on project ActiveState-CLI/Python3-Import") + cp.Expect("Operating on project") + cp.Expect("ActiveState-CLI/Python3-Import") cp.ExpectExitCode(0) cp = ts.Spawn("packages") diff --git a/test/integration/init_int_test.go b/test/integration/init_int_test.go index d8885e6a42..474396279a 100644 --- a/test/integration/init_int_test.go +++ b/test/integration/init_int_test.go @@ -62,7 +62,7 @@ func (suite *InitIntegrationTestSuite) runInitTest(addPath bool, lang string, ex // Run `state init`, creating the project. cp := ts.Spawn(computedArgs...) cp.Expect("Skipping runtime setup") - cp.ExpectLongString(fmt.Sprintf("Project '%s' has been successfully initialized", namespace)) + cp.Expect(fmt.Sprintf("Project '%s' has been successfully initialized", namespace)) cp.ExpectExitCode(0) ts.NotifyProjectCreated(e2e.PersistentUsername, pname.String()) @@ -114,8 +114,8 @@ func (suite *InitIntegrationTestSuite) TestInit_InferLanguageFromUse() { cp.ExpectExitCode(0) cp = ts.SpawnWithOpts( - e2e.WithArgs("use", "Python3"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("use", "Python3"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.Expect("Switched to project") cp.ExpectExitCode(0) @@ -137,7 +137,7 @@ func (suite *InitIntegrationTestSuite) TestInit_NotAuthenticated() { defer ts.Close() cp := ts.Spawn("init", "test-user/test-project", "python3") - cp.ExpectLongString("You need to be authenticated to initialize a project.") + cp.Expect("You need to be authenticated to initialize a project.") } func TestInitIntegrationTestSuite(t *testing.T) { diff --git a/test/integration/install_scripts_int_test.go b/test/integration/install_scripts_int_test.go index 891a41a2aa..668a9b94d8 100644 --- a/test/integration/install_scripts_int_test.go +++ b/test/integration/install_scripts_int_test.go @@ -5,10 +5,14 @@ import ( "fmt" "path/filepath" "runtime" - "strings" "testing" "time" + "github.com/ActiveState/termtest" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + "github.com/thoas/go-funk" + "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/environment" "github.com/ActiveState/cli/internal/fileutils" @@ -17,10 +21,6 @@ import ( "github.com/ActiveState/cli/internal/osutils" "github.com/ActiveState/cli/internal/testhelpers/e2e" "github.com/ActiveState/cli/internal/testhelpers/tagsuite" - "github.com/ActiveState/termtest" - "github.com/stretchr/testify/require" - "github.com/stretchr/testify/suite" - "github.com/thoas/go-funk" ) type InstallScriptsIntegrationTestSuite struct { @@ -90,18 +90,18 @@ func (suite *InstallScriptsIntegrationTestSuite) TestInstall() { appInstallDir := filepath.Join(ts.Dirs.Work, "app") suite.NoError(fileutils.Mkdir(appInstallDir)) - var cp *termtest.ConsoleProcess + var cp *e2e.SpawnedCmd if runtime.GOOS != "windows" { cp = ts.SpawnCmdWithOpts( - "bash", e2e.WithArgs(argsWithActive...), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), - e2e.AppendEnv(fmt.Sprintf("%s=%s", constants.AppInstallDirOverrideEnvVarName, appInstallDir)), + "bash", e2e.OptArgs(argsWithActive...), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptAppendEnv(fmt.Sprintf("%s=%s", constants.AppInstallDirOverrideEnvVarName, appInstallDir)), ) } else { - cp = ts.SpawnCmdWithOpts("powershell.exe", e2e.WithArgs(argsWithActive...), - e2e.AppendEnv("SHELL="), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), - e2e.AppendEnv(fmt.Sprintf("%s=%s", constants.AppInstallDirOverrideEnvVarName, appInstallDir)), + cp = ts.SpawnCmdWithOpts("powershell.exe", e2e.OptArgs(argsWithActive...), + e2e.OptAppendEnv("SHELL="), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptAppendEnv(fmt.Sprintf("%s=%s", constants.AppInstallDirOverrideEnvVarName, appInstallDir)), ) } @@ -109,9 +109,9 @@ func (suite *InstallScriptsIntegrationTestSuite) TestInstall() { if tt.Activate != "" || tt.ActivateByCommand != "" { cp.Expect("Creating a Virtual Environment") - cp.Expect("Quick Start", time.Second*60) + cp.Expect("Quick Start", termtest.OptExpectTimeout(time.Second*60)) // ensure that shell is functional - cp.WaitForInput() + cp.ExpectInput() cp.SendLine("python3 -c \"import sys; print(sys.copyright)\"") cp.Expect("ActiveState") @@ -135,14 +135,14 @@ func (suite *InstallScriptsIntegrationTestSuite) TestInstall() { // Verify that can install overtop if runtime.GOOS != "windows" { - cp = ts.SpawnCmdWithOpts("bash", e2e.WithArgs(argsPlain...)) + cp = ts.SpawnCmdWithOpts("bash", e2e.OptArgs(argsPlain...)) } else { - cp = ts.SpawnCmdWithOpts("powershell.exe", e2e.WithArgs(argsPlain...), - e2e.AppendEnv("SHELL="), + cp = ts.SpawnCmdWithOpts("powershell.exe", e2e.OptArgs(argsPlain...), + e2e.OptAppendEnv("SHELL="), ) } cp.Expect("successfully installed") - cp.WaitForInput() + cp.ExpectInput() cp.SendLine("exit") cp.ExpectExitCode(0) }) @@ -157,14 +157,18 @@ func (suite *InstallScriptsIntegrationTestSuite) TestInstall_NonEmptyTarget() { script := scriptPath(suite.T(), ts.Dirs.Work) argsPlain := []string{script, "-t", ts.Dirs.Work} argsPlain = append(argsPlain, "-b", constants.BranchName) - var cp *termtest.ConsoleProcess + var cp *e2e.SpawnedCmd if runtime.GOOS != "windows" { - cp = ts.SpawnCmdWithOpts("bash", e2e.WithArgs(argsPlain...)) + cp = ts.SpawnCmdWithOpts("bash", e2e.OptArgs(argsPlain...)) } else { - cp = ts.SpawnCmdWithOpts("powershell.exe", e2e.WithArgs(argsPlain...), e2e.AppendEnv("SHELL=")) + cp = ts.SpawnCmdWithOpts("powershell.exe", e2e.OptArgs(argsPlain...), e2e.OptAppendEnv("SHELL=")) } - cp.ExpectLongString("Installation path must be an empty directory") - cp.Wait() + cp.Expect("Installation path must be an empty directory") + + // Originally this was ExpectExitCode(1), but particularly on Windows this turned out to be unreliable. Probably + // because of powershell. + // Since we asserted the expected error above we don't need to go on a wild goose chase here. + cp.ExpectExit() } func (suite *InstallScriptsIntegrationTestSuite) TestInstall_VersionDoesNotExist() { @@ -175,14 +179,14 @@ func (suite *InstallScriptsIntegrationTestSuite) TestInstall_VersionDoesNotExist script := scriptPath(suite.T(), ts.Dirs.Work) args := []string{script, "-t", ts.Dirs.Work} args = append(args, "-v", "does-not-exist") - var cp *termtest.ConsoleProcess + var cp *e2e.SpawnedCmd if runtime.GOOS != "windows" { - cp = ts.SpawnCmdWithOpts("bash", e2e.WithArgs(args...)) + cp = ts.SpawnCmdWithOpts("bash", e2e.OptArgs(args...)) } else { - cp = ts.SpawnCmdWithOpts("powershell.exe", e2e.WithArgs(args...), e2e.AppendEnv("SHELL=")) + cp = ts.SpawnCmdWithOpts("powershell.exe", e2e.OptArgs(args...), e2e.OptAppendEnv("SHELL=")) } cp.Expect("Could not download") - cp.ExpectLongString("does-not-exist") + cp.Expect("does-not-exist") cp.ExpectExitCode(1) } @@ -208,9 +212,9 @@ func scriptPath(t *testing.T, targetDir string) string { return target } -func expectStateToolInstallation(cp *termtest.ConsoleProcess) { +func expectStateToolInstallation(cp *e2e.SpawnedCmd) { cp.Expect("Preparing Installer for State Tool Package Manager") - cp.Expect("Installation Complete", time.Minute) + cp.Expect("Installation Complete", termtest.OptExpectTimeout(time.Minute)) } // assertBinDirContents checks if given files are or are not in the bin directory @@ -242,8 +246,8 @@ func (suite *InstallScriptsIntegrationTestSuite) assertCorrectVersion(ts *e2e.Se cp := ts.SpawnCmd(stateExec, "--version", "--output=json") cp.ExpectExitCode(0) actual := versionData{} - out := strings.Trim(cp.TrimmedSnapshot(), "\x00") - json.Unmarshal([]byte(out), &actual) + out := cp.StrippedSnapshot() + suite.Require().NoError(json.Unmarshal([]byte(out), &actual)) if expectedVersion != "" { suite.Equal(expectedVersion, actual.Version) diff --git a/test/integration/languages_int_test.go b/test/integration/languages_int_test.go index c6b926e99f..801947c3c0 100644 --- a/test/integration/languages_int_test.go +++ b/test/integration/languages_int_test.go @@ -5,6 +5,7 @@ import ( "testing" "time" + "github.com/ActiveState/termtest" goversion "github.com/hashicorp/go-version" "github.com/stretchr/testify/suite" @@ -62,7 +63,7 @@ func (suite *LanguagesIntegrationTestSuite) TestLanguages_install() { cp = ts.Spawn("languages", "install", "python@3.9.16") cp.Expect("Language added: python@3.9.16") // This can take a little while - cp.ExpectExitCode(0, 60*time.Second) + cp.ExpectExitCode(0, termtest.OptExpectTimeout(60*time.Second)) cp = ts.Spawn("languages") cp.Expect("Name") @@ -72,7 +73,7 @@ func (suite *LanguagesIntegrationTestSuite) TestLanguages_install() { cp.ExpectExitCode(0) // assert that version number changed - output := cp.MatchState().TermState.StringBeforeCursor() + output := cp.Output() vs := versionRe.FindString(output) v, err := goversion.NewVersion(vs) suite.Require().NoError(err, "parsing version %s", vs) diff --git a/test/integration/msg_int_test.go b/test/integration/msg_int_test.go index c0070df1da..546c66dc22 100644 --- a/test/integration/msg_int_test.go +++ b/test/integration/msg_int_test.go @@ -24,7 +24,7 @@ func (suite *MsgIntegrationTestSuite) TestMessage_None() { // We test on config as it just dumps help and has minimal output // The base state command would also work, but it's output is more verbose and termtest likes to cut off content if it's too long - cp := ts.SpawnWithOpts(e2e.WithArgs("config")) + cp := ts.SpawnWithOpts(e2e.OptArgs("config")) cp.Expect("Usage:") cp.ExpectExitCode(0) @@ -77,7 +77,7 @@ func (suite *MsgIntegrationTestSuite) TestMessage_Basic() { // We test on config as it just dumps help and has minimal output // The base state command would also work, but it's output is more verbose and termtest likes to cut off content if it's too long - cp := ts.SpawnWithOpts(e2e.WithArgs("config"), e2e.AppendEnv(constants.MessagesOverrideEnvVarName+"="+msgFile)) + cp := ts.SpawnWithOpts(e2e.OptArgs("config"), e2e.OptAppendEnv(constants.MessagesOverrideEnvVarName+"="+msgFile)) cp.Expect(`This is a simple message`) cp.Expect("Usage:") cp.ExpectExitCode(0) @@ -89,7 +89,7 @@ func (suite *MsgIntegrationTestSuite) TestMessage_Basic() { } cp.ExpectExitCode(0) if !tt.ExpectRepeat { - suite.Require().NotContains(cp.Snapshot(), "This is a simple message", "Should not repeat as that's the default behavior") + suite.Require().NotContains(cp.Output(), "This is a simple message", "Should not repeat as that's the default behavior") } }) } @@ -111,7 +111,7 @@ func (suite *MsgIntegrationTestSuite) TestMessage_Basic_PlacementAfter() { // We test on config as it just dumps help and has minimal output // The base state command would also work, but it's output is more verbose and termtest likes to cut off content if it's too long - cp := ts.SpawnWithOpts(e2e.WithArgs("config"), e2e.AppendEnv(constants.MessagesOverrideEnvVarName+"="+msgFile)) + cp := ts.SpawnWithOpts(e2e.OptArgs("config"), e2e.OptAppendEnv(constants.MessagesOverrideEnvVarName+"="+msgFile)) cp.Expect("Usage:") cp.Expect(`This is a simple message`) cp.ExpectExitCode(0) @@ -132,21 +132,21 @@ func (suite *MsgIntegrationTestSuite) TestMessage_Basic_InterruptPrompt() { ]`, graph.MessageInterruptTypePrompt)), 0755) suite.Require().NoError(err) - cp := ts.SpawnWithOpts(e2e.WithArgs("config"), e2e.AppendEnv(constants.MessagesOverrideEnvVarName+"="+msgFile)) + cp := ts.SpawnWithOpts(e2e.OptArgs("config"), e2e.OptAppendEnv(constants.MessagesOverrideEnvVarName+"="+msgFile)) cp.Expect(`This is a simple message`) cp.Expect("Press ENTER to continue") time.Sleep(time.Millisecond * 100) - suite.Require().NotContains(cp.Snapshot(), "Usage:") - cp.SendLine("") + suite.Require().NotContains(cp.Output(), "Usage:") + cp.SendEnter() cp.Expect("Usage:") cp.ExpectExitCode(0) // Test that non-interactive does not prompt - cp = ts.SpawnWithOpts(e2e.WithArgs("config", "-n"), e2e.AppendEnv(constants.MessagesOverrideEnvVarName+"="+msgFile)) + cp = ts.SpawnWithOpts(e2e.OptArgs("config", "-n"), e2e.OptAppendEnv(constants.MessagesOverrideEnvVarName+"="+msgFile)) cp.Expect(`This is a simple message`) cp.Expect("Usage:") cp.ExpectExitCode(0) - suite.Require().NotContains(cp.Snapshot(), "Press ENTER to continue") + suite.Require().NotContains(cp.Output(), "Press ENTER to continue") } func (suite *MsgIntegrationTestSuite) TestMessage_Basic_InterruptExit() { @@ -163,10 +163,10 @@ func (suite *MsgIntegrationTestSuite) TestMessage_Basic_InterruptExit() { ]`, graph.MessageInterruptTypeExit)), 0755) suite.Require().NoError(err) - cp := ts.SpawnWithOpts(e2e.WithArgs("config"), e2e.AppendEnv(constants.MessagesOverrideEnvVarName+"="+msgFile)) - cp.Expect(`This is a simple message`) + cp := ts.SpawnWithOpts(e2e.OptArgs("config"), e2e.OptAppendEnv(constants.MessagesOverrideEnvVarName+"="+msgFile)) cp.ExpectExitCode(1) - suite.Require().NotContains(cp.Snapshot(), "Usage:") + suite.Require().Contains(cp.Snapshot(), "This is a simple message") + suite.Require().NotContains(cp.Output(), "Usage:") } func TestMsgIntegrationTestSuite(t *testing.T) { diff --git a/test/integration/offinstall_int_test.go b/test/integration/offinstall_int_test.go index b79c7da7f5..83d21b8cb5 100644 --- a/test/integration/offinstall_int_test.go +++ b/test/integration/offinstall_int_test.go @@ -11,6 +11,7 @@ import ( "testing" "time" + "github.com/ActiveState/termtest" "github.com/mholt/archiver" "github.com/ActiveState/cli/internal/analytics/client/sync/reporters" @@ -112,14 +113,14 @@ func (suite *OffInstallIntegrationTestSuite) TestInstallAndUninstall() { if runtime.GOOS == "windows" { refreshEnv := filepath.Join(environment.GetRootPathUnsafe(), "test", "integration", "testdata", "tools", "refreshenv", "refreshenv.bat") tp := ts.SpawnCmd("cmd", "/C", refreshEnv+" && "+defaultInstalledExecutable) - tp.Expect("TEST REPLACEMENT", 5*time.Second) + tp.Expect("TEST REPLACEMENT", termtest.OptExpectTimeout(5*time.Second)) tp.ExpectExitCode(0) } else { // Disabled for now: DX-1307 // tp = ts.SpawnCmd("bash") - // time.Sleep(1 * time.Second) // Give zsh a second to start -- can't use WaitForInput as it doesn't respect a custom HOME dir + // time.Sleep(1 * time.Second) // Give zsh a second to start -- can't use ExpectInput as it doesn't respect a custom HOME dir // tp.Send("test-offline-install") - // tp.Expect("TEST REPLACEMENT", 5*time.Second) + // tp.Expect("TEST REPLACEMENT", termtest.OptExpectTimeout(5*time.Second)) // tp.Send("exit") // tp.ExpectExitCode(0) } @@ -128,14 +129,14 @@ func (suite *OffInstallIntegrationTestSuite) TestInstallAndUninstall() { { // Uninstall tp := ts.SpawnCmdWithOpts( suite.uninstallerPath, - e2e.WithArgs(defaultInstallDir), - e2e.AppendEnv(env...), + e2e.OptArgs(defaultInstallDir), + e2e.OptAppendEnv(env...), ) tp.Expect("continue?") tp.SendLine("y") - tp.Expect("Uninstall Complete", 5*time.Second) + tp.Expect("Uninstall Complete", termtest.OptExpectTimeout(5*time.Second)) tp.Expect("Press enter to exit") - tp.SendLine("") + tp.SendEnter() tp.ExpectExitCode(0) // Ensure shell env is updated @@ -171,11 +172,11 @@ func (suite *OffInstallIntegrationTestSuite) TestInstallNoPermission() { tp := ts.SpawnCmdWithOpts( suite.installerPath, - e2e.WithArgs(pathWithNoPermission), + e2e.OptArgs(pathWithNoPermission), ) - tp.Expect("Please ensure that the directory is writeable", 5*time.Second) - tp.Expect("Press enter to exit", 5*time.Second) - tp.SendLine("") + tp.Expect("Please ensure that the directory is writeable", termtest.OptExpectTimeout(5*time.Second)) + tp.Expect("Press enter to exit", termtest.OptExpectTimeout(5*time.Second)) + tp.SendEnter() tp.ExpectExitCode(1) } @@ -295,17 +296,17 @@ func (suite *OffInstallIntegrationTestSuite) TestInstallTwice() { // Running offline installer again should not cause an error tp := ts.SpawnCmdWithOpts( suite.installerPath, - e2e.WithArgs(defaultInstallDir), - e2e.AppendEnv(env...), + e2e.OptArgs(defaultInstallDir), + e2e.OptAppendEnv(env...), ) tp.Expect("Installation directory is not empty") tp.Send("y") - tp.Expect("Do you accept the ActiveState Runtime Installer License Agreement? (y/N)", 5*time.Second) + tp.Expect("Do you accept the ActiveState Runtime Installer License Agreement? (y/N)", termtest.OptExpectTimeout(5*time.Second)) tp.Send("y") - tp.Expect("Extracting", time.Second) + tp.Expect("Extracting", termtest.OptExpectTimeout(time.Second)) tp.Expect("Installation complete") tp.Expect("Press enter to exit") - tp.SendLine("") + tp.SendEnter() tp.ExpectExitCode(0) // Uninstall @@ -315,30 +316,30 @@ func (suite *OffInstallIntegrationTestSuite) TestInstallTwice() { func (suite *OffInstallIntegrationTestSuite) runOfflineInstaller(ts *e2e.Session, installDir string, env []string) { tp := ts.SpawnCmdWithOpts( suite.installerPath, - e2e.WithArgs(installDir), - e2e.AppendEnv(env...), + e2e.OptArgs(installDir), + e2e.OptAppendEnv(env...), ) - tp.Expect("Do you accept the ActiveState Runtime Installer License Agreement? (y/N)", 5*time.Second) + tp.Expect("Do you accept the ActiveState Runtime Installer License Agreement? (y/N)", termtest.OptExpectTimeout(5*time.Second)) tp.Send("y") - tp.Expect("Extracting", time.Second) + tp.Expect("Extracting", termtest.OptExpectTimeout(time.Second)) tp.Expect("Installing") tp.Expect("Installation complete") tp.Expect("Press enter to exit") - tp.SendLine("") + tp.SendEnter() tp.ExpectExitCode(0) } func (suite *OffInstallIntegrationTestSuite) runOfflineUninstaller(ts *e2e.Session, installDir string, env []string) { tp := ts.SpawnCmdWithOpts( suite.uninstallerPath, - e2e.WithArgs(installDir), - e2e.AppendEnv(env...), + e2e.OptArgs(installDir), + e2e.OptAppendEnv(env...), ) tp.Expect("continue?") tp.SendLine("y") - tp.Expect("Uninstall Complete", 5*time.Second) + tp.Expect("Uninstall Complete", termtest.OptExpectTimeout(5*time.Second)) tp.Expect("Press enter to exit") - tp.SendLine("") + tp.SendEnter() tp.ExpectExitCode(0) } @@ -402,8 +403,8 @@ func (suite *OffInstallIntegrationTestSuite) preparePayload(ts *e2e.Session, pay // Append our assets to the installer executable tp := ts.SpawnCmdWithOpts("gozip", - e2e.WithWorkDirectory(buildPath), - e2e.WithArgs( + e2e.OptWD(buildPath), + e2e.OptArgs( "-c", suite.installerPath, filepath.Base(payloadMockPath), "installer_config.json", diff --git a/test/integration/package_int_test.go b/test/integration/package_int_test.go index 213f9c6a3d..6fc2e8bcba 100644 --- a/test/integration/package_int_test.go +++ b/test/integration/package_int_test.go @@ -8,11 +8,13 @@ import ( "testing" "time" + "github.com/ActiveState/termtest" + "github.com/stretchr/testify/suite" + "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/fileutils" "github.com/ActiveState/cli/internal/testhelpers/e2e" "github.com/ActiveState/cli/internal/testhelpers/tagsuite" - "github.com/stretchr/testify/suite" ) type PackageIntegrationTestSuite struct { @@ -27,7 +29,8 @@ func (suite *PackageIntegrationTestSuite) TestPackage_listingSimple() { suite.PrepareActiveStateYAML(ts) cp := ts.Spawn("packages") - cp.ExpectLongString("Operating on project ActiveState-CLI/List") + cp.Expect("Operating on project") + cp.Expect("ActiveState-CLI/List") cp.Expect("Name") cp.Expect("pytest") cp.ExpectExitCode(0) @@ -85,7 +88,7 @@ func (suite *PackageIntegrationTestSuite) TestPackages_project_invalid() { defer ts.Close() cp := ts.Spawn("packages", "--namespace", "junk/junk") - cp.ExpectLongString("The requested project junk/junk could not be found") + cp.Expect("The requested project junk/junk could not be found") cp.ExpectExitCode(1) } @@ -169,7 +172,7 @@ func (suite *PackageIntegrationTestSuite) TestPackage_searchWithExactTerm() { "older versions", } for _, expectation := range expectations { - cp.ExpectLongString(expectation) + cp.Expect(expectation) } cp.ExpectExitCode(0) } @@ -181,11 +184,11 @@ func (suite *PackageIntegrationTestSuite) TestPackage_searchWithExactTermWrongTe suite.PrepareActiveStateYAML(ts) cp := ts.Spawn("search", "Requests", "--exact-term") - cp.ExpectLongString("No packages in our catalog match") + cp.Expect("No packages in our catalog match") cp.ExpectExitCode(1) cp = ts.Spawn("search", "xxxrequestsxxx", "--exact-term") - cp.ExpectLongString("No packages in our catalog match") + cp.Expect("No packages in our catalog match") cp.ExpectExitCode(1) } @@ -228,7 +231,7 @@ func (suite *PackageIntegrationTestSuite) TestPackage_searchWithWrongLang() { suite.PrepareActiveStateYAML(ts) cp := ts.Spawn("search", "xxxjunkxxx", "--language=perl") - cp.ExpectLongString("No packages in our catalog match") + cp.Expect("No packages in our catalog match") cp.ExpectExitCode(1) } @@ -298,31 +301,33 @@ func (suite *PackageIntegrationTestSuite) TestPackage_import() { namespace := fmt.Sprintf("%s/%s", username, "Python3") cp := ts.Spawn("init", "--language", "python", namespace, ts.Dirs.Work) - cp.ExpectLongString("successfully initialized") + cp.Expect("successfully initialized") cp.ExpectExitCode(0) reqsFilePath := filepath.Join(cp.WorkDirectory(), reqsFileName) suite.Run("invalid requirements.txt", func() { + ts.SetT(suite.T()) ts.PrepareFile(reqsFilePath, badReqsData) cp := ts.Spawn("import", "requirements.txt") - cp.ExpectNotExitCode(0, time.Second*60) + cp.ExpectNotExitCode(0) }) suite.Run("valid requirements.txt", func() { + ts.SetT(suite.T()) ts.PrepareFile(reqsFilePath, reqsData) cp := ts.Spawn("import", "requirements.txt") - cp.ExpectExitCode(0, time.Second*60) + cp.ExpectExitCode(0) cp = ts.Spawn("push") - cp.ExpectExitCode(0, time.Second*60) + cp.ExpectExitCode(0) cp = ts.Spawn("import", "requirements.txt") - cp.Expect("Are you sure you want to do this") - cp.Send("n") - cp.ExpectNotExitCode(0, time.Second*60) + cp.Expect("Are you sure") + cp.SendLine("n") + cp.ExpectNotExitCode(0) }) } @@ -349,19 +354,19 @@ func (suite *PackageIntegrationTestSuite) TestPackage_headless_operation() { suite.Run("install", func() { cp := ts.Spawn("install", "dateparser@0.7.2") - cp.ExpectRe("(?:Package added|being built)", 30*time.Second) + cp.ExpectRe("(?:Package added|being built)", termtest.OptExpectTimeout(30*time.Second)) cp.Wait() }) suite.Run("install (update)", func() { cp := ts.Spawn("install", "dateparser@0.7.6") - cp.ExpectRe("(?:Package updated|being built)", 50*time.Second) + cp.ExpectRe("(?:Package updated|being built)", termtest.OptExpectTimeout(50*time.Second)) cp.Wait() }) suite.Run("uninstall", func() { cp := ts.Spawn("uninstall", "dateparser") - cp.ExpectRe("(?:Package uninstalled|being built)", 30*time.Second) + cp.ExpectRe("(?:Package uninstalled|being built)", termtest.OptExpectTimeout(30*time.Second)) cp.Wait() }) } @@ -391,22 +396,22 @@ func (suite *PackageIntegrationTestSuite) TestPackage_operation() { suite.Run("install", func() { cp := ts.Spawn("install", "urllib3@1.25.6") - cp.ExpectLongString(fmt.Sprintf("Operating on project %s/python3-pkgtest", username)) - cp.ExpectRe("(?:Package added|being built)", 30*time.Second) + cp.Expect(fmt.Sprintf("Operating on project %s/python3-pkgtest", username)) + cp.ExpectRe("(?:Package added|being built)", termtest.OptExpectTimeout(30*time.Second)) cp.Wait() }) suite.Run("install (update)", func() { cp := ts.Spawn("install", "urllib3@1.25.8") - cp.ExpectLongString(fmt.Sprintf("Operating on project %s/python3-pkgtest", username)) - cp.ExpectRe("(?:Package updated|being built)", 30*time.Second) + cp.Expect(fmt.Sprintf("Operating on project %s/python3-pkgtest", username)) + cp.ExpectRe("(?:Package updated|being built)", termtest.OptExpectTimeout(30*time.Second)) cp.Wait() }) suite.Run("uninstall", func() { cp := ts.Spawn("uninstall", "urllib3") - cp.ExpectLongString(fmt.Sprintf("Operating on project %s/python3-pkgtest", username)) - cp.ExpectRe("(?:Package uninstalled|being built)", 30*time.Second) + cp.Expect(fmt.Sprintf("Operating on project %s/python3-pkgtest", username)) + cp.ExpectRe("(?:Package uninstalled|being built)", termtest.OptExpectTimeout(30*time.Second)) cp.Wait() }) } @@ -426,7 +431,7 @@ func (suite *PackageIntegrationTestSuite) TestPackage_Duplicate() { cp.ExpectExitCode(0) cp = ts.Spawn("install", "requests") // install again - cp.ExpectLongString("No new changes to commit") + cp.Expect("No new changes to commit") cp.ExpectNotExitCode(0) } @@ -454,11 +459,11 @@ func (suite *PackageIntegrationTestSuite) TestInstall_Empty() { defer ts.Close() cp := ts.SpawnWithOpts( - e2e.WithArgs("install", "JSON"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("install", "JSON"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.Expect("Installing Package") - cp.ExpectExitCode(0) + cp.ExpectExitCode(0, termtest.OptExpectTimeout(120*time.Second)) configFilepath := filepath.Join(ts.Dirs.Work, constants.ConfigFileName) suite.Require().FileExists(configFilepath) @@ -497,10 +502,10 @@ func (suite *PackageIntegrationTestSuite) TestJSON() { AssertValidJSON(suite.T(), cp) cp = ts.SpawnWithOpts( - e2e.WithArgs("install", "Text-CSV", "--output", "editor"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("install", "Text-CSV", "--output", "editor"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) - cp.Expect(`{"name":"Text-CSV"`) + cp.Expect(`{"name":"Text-CSV"`, termtest.OptExpectTimeout(120*time.Second)) cp.ExpectExitCode(0) AssertValidJSON(suite.T(), cp) @@ -510,8 +515,8 @@ func (suite *PackageIntegrationTestSuite) TestJSON() { AssertValidJSON(suite.T(), cp) cp = ts.SpawnWithOpts( - e2e.WithArgs("uninstall", "Text-CSV", "-o", "json"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("uninstall", "Text-CSV", "-o", "json"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.Expect(`{"name":"Text-CSV"`) cp.ExpectExitCode(0) @@ -530,17 +535,17 @@ func (suite *PackageIntegrationTestSuite) TestNormalize() { dir := filepath.Join(ts.Dirs.Work, "normalized") suite.Require().NoError(fileutils.Mkdir(dir)) cp := ts.SpawnWithOpts( - e2e.WithArgs("checkout", "ActiveState-CLI/small-python", "."), - e2e.WithWorkDirectory(dir), + e2e.OptArgs("checkout", "ActiveState-CLI/small-python", "."), + e2e.OptWD(dir), ) cp.Expect("Skipping runtime setup") cp.Expect("Checked out project") cp.ExpectExitCode(0) cp = ts.SpawnWithOpts( - e2e.WithArgs("install", "Charset_normalizer"), - e2e.WithWorkDirectory(dir), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("install", "Charset_normalizer"), + e2e.OptWD(dir), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.Expect("charset-normalizer") cp.Expect("is different") @@ -550,21 +555,21 @@ func (suite *PackageIntegrationTestSuite) TestNormalize() { anotherDir := filepath.Join(ts.Dirs.Work, "not-normalized") suite.Require().NoError(fileutils.Mkdir(anotherDir)) cp = ts.SpawnWithOpts( - e2e.WithArgs("checkout", "ActiveState-CLI/small-python", "."), - e2e.WithWorkDirectory(anotherDir), + e2e.OptArgs("checkout", "ActiveState-CLI/small-python", "."), + e2e.OptWD(anotherDir), ) cp.Expect("Skipping runtime setup") cp.Expect("Checked out project") cp.ExpectExitCode(0) cp = ts.SpawnWithOpts( - e2e.WithArgs("install", "charset-normalizer"), - e2e.WithWorkDirectory(anotherDir), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("install", "charset-normalizer"), + e2e.OptWD(anotherDir), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.Expect("charset-normalizer") cp.ExpectExitCode(0) - suite.NotContains(cp.TrimmedSnapshot(), "is different") + suite.NotContains(cp.Output(), "is different") } func (suite *PackageIntegrationTestSuite) TestInstall_InvalidVersion() { @@ -578,12 +583,11 @@ func (suite *PackageIntegrationTestSuite) TestInstall_InvalidVersion() { cp.ExpectExitCode(0) cp = ts.SpawnWithOpts( - e2e.WithArgs("install", "pytest@999.9999.9999"), - e2e.AppendEnv(constants.DisableRuntime+"=false"), + e2e.OptArgs("install", "pytest@999.9999.9999"), + e2e.OptAppendEnv(constants.DisableRuntime+"=false"), ) cp.Expect("Error occurred while trying to create a commit") cp.ExpectExitCode(1) - cp.Wait() } func (suite *PackageIntegrationTestSuite) TestUpdate_InvalidVersion() { @@ -600,8 +604,8 @@ func (suite *PackageIntegrationTestSuite) TestUpdate_InvalidVersion() { cp.ExpectExitCode(0) cp = ts.SpawnWithOpts( - e2e.WithArgs("install", "pytest@999.9999.9999"), // update - e2e.AppendEnv(constants.DisableRuntime+"=false"), // We DO want to test the runtime part, just not for every step + e2e.OptArgs("install", "pytest@999.9999.9999"), // update + e2e.OptAppendEnv(constants.DisableRuntime+"=false"), // We DO want to test the runtime part, just not for every step ) cp.Expect("Error occurred while trying to create a commit") cp.ExpectExitCode(1) @@ -631,8 +635,8 @@ func (suite *PackageIntegrationTestSuite) TestUpdate() { cp.ExpectExitCode(0) cp = ts.SpawnWithOpts( - e2e.WithArgs("install", "pytest@7.4.0"), // update - e2e.AppendEnv(constants.DisableRuntime+"=false"), // We DO want to test the runtime part, just not for every step + e2e.OptArgs("install", "pytest@7.4.0"), // update + e2e.OptAppendEnv(constants.DisableRuntime+"=false"), // We DO want to test the runtime part, just not for every step ) cp.ExpectExitCode(0) @@ -663,8 +667,8 @@ func (suite *PackageIntegrationTestSuite) TestRuby() { cp.ExpectExitCode(0) cp = ts.SpawnWithOpts( - e2e.WithArgs("exec", "rake", "--", "--version"), - e2e.AppendEnv(constants.DisableRuntime+"=false"), + e2e.OptArgs("exec", "rake", "--", "--version"), + e2e.OptAppendEnv(constants.DisableRuntime+"=false"), ) cp.ExpectRe(`rake, version \d+\.\d+\.\d+`) cp.ExpectExitCode(0) @@ -685,14 +689,14 @@ func (suite *PackageIntegrationTestSuite) TestProjectWithOfflineInstallerAndDock cp.ExpectExitCode(0) cp = ts.SpawnWithOpts( - e2e.WithArgs("install", "requests"), - e2e.AppendEnv(constants.DisableRuntime+"=false"), + e2e.OptArgs("install", "requests"), + e2e.OptAppendEnv(constants.DisableRuntime+"=false"), ) cp.ExpectExitCode(0) cp = ts.SpawnWithOpts( - e2e.WithArgs("uninstall", "requests"), - e2e.AppendEnv(constants.DisableRuntime+"=false"), + e2e.OptArgs("uninstall", "requests"), + e2e.OptAppendEnv(constants.DisableRuntime+"=false"), ) cp.ExpectExitCode(0) } diff --git a/test/integration/performance_expansion_int_test.go b/test/integration/performance_expansion_int_test.go index 823a5caff2..d1debfa6c3 100644 --- a/test/integration/performance_expansion_int_test.go +++ b/test/integration/performance_expansion_int_test.go @@ -44,26 +44,28 @@ func (suite *PerformanceExpansionIntegrationTestSuite) startSvc(ts *e2e.Session) func (suite *PerformanceExpansionIntegrationTestSuite) TestExpansionPerformance() { suite.OnlyRunForTags(tagsuite.Performance) baseline := DefaultMaxTime - suite.Run("CallScript", func() { - median := suite.testScriptPerformance(scriptPerformanceOptions{ - script: projectfile.Script{ - NameVal: projectfile.NameVal{ - Name: "call-script", - Value: `echo "Hello World"`, - }, - ScriptFields: projectfile.ScriptFields{ - Language: "bash", - }, + + // Establish baseline + // Must not be called as a subtest as it breaks the running of other subtests + median := suite.testScriptPerformance(scriptPerformanceOptions{ + script: projectfile.Script{ + NameVal: projectfile.NameVal{ + Name: "call-script", + Value: `echo "Hello World"`, }, - expect: "Hello World", - samples: DefaultSamples, - max: DefaultMaxTime, - }) - variance := float64(median) + (float64(median) * DefaultVariance) - baseline = time.Duration(variance) + ScriptFields: projectfile.ScriptFields{ + Language: "bash", + }, + }, + expect: "Hello World", + samples: DefaultSamples, + max: DefaultMaxTime, + verbose: true, }) + variance := float64(median) + (float64(median) * DefaultVariance) + baseline = time.Duration(variance) - suite.Require().NotEqual(baseline, DefaultMaxTime) + suite.Require().NotEqual(DefaultMaxTime, baseline) suite.Run("CallScriptFromMerged", func() { additionalYamls := make(map[string]projectfile.Project) @@ -150,7 +152,7 @@ func (suite *PerformanceExpansionIntegrationTestSuite) TestExpansionPerformance( Language: "bash", }, }, - //expect: "Yaml-Test", // TODO: re-enable in https://activestatef.atlassian.net/browse/DX-1312 + expect: "Yaml-Test", samples: DefaultSamples, max: baseline, }) @@ -201,9 +203,10 @@ func (suite *PerformanceExpansionIntegrationTestSuite) TestExpansionPerformance( Language: "bash", }, }, - // expect: "https://platform.activestate.com/ActiveState-CLI/Yaml-Test", // TODO: re-enable in https://activestatef.atlassian.net/browse/DX-1312 + expect: "https://platform.activestate.com/ActiveState-CLI/Yaml-Test", samples: DefaultSamples, max: baseline, + verbose: true, }) }) @@ -346,6 +349,7 @@ type scriptPerformanceOptions struct { additionalScripts projectfile.Scripts constants projectfile.Constants additionalYamlFiles map[string]projectfile.Project + verbose bool } func (suite *PerformanceExpansionIntegrationTestSuite) testScriptPerformance(opts scriptPerformanceOptions) time.Duration { @@ -378,7 +382,7 @@ func (suite *PerformanceExpansionIntegrationTestSuite) testScriptPerformance(opt suite.prepareAlternateActiveStateYaml(name, string(contents), ts) } - return performanceTest([]string{"run", opts.script.Name}, opts.expect, opts.samples, opts.max, suite.Suite, ts) + return performanceTest([]string{"run", opts.script.Name}, opts.expect, opts.samples, opts.max, opts.verbose, suite.Suite, ts) } func (suite *PerformanceExpansionIntegrationTestSuite) prepareAlternateActiveStateYaml(name, contents string, ts *e2e.Session) { diff --git a/test/integration/performance_int_test.go b/test/integration/performance_int_test.go index cc1e268b80..173f731cee 100644 --- a/test/integration/performance_int_test.go +++ b/test/integration/performance_int_test.go @@ -1,7 +1,10 @@ package integration import ( + "bytes" "fmt" + "io" + "log" "regexp" "sort" "strconv" @@ -11,6 +14,7 @@ import ( "github.com/ActiveState/cli/internal/errs" "github.com/ActiveState/cli/internal/exeutils" + "github.com/ActiveState/termtest" "github.com/stretchr/testify/suite" "github.com/ActiveState/cli/internal/testhelpers/e2e" @@ -35,37 +39,48 @@ func (suite *PerformanceIntegrationTestSuite) TestVersionPerformance() { stdout, stderr, err := exeutils.ExecSimple(ts.SvcExe, []string{"start"}, []string{}) suite.Require().NoError(err, fmt.Sprintf("Full error:\n%v\nstdout:\n%s\nstderr:\n%s", errs.JoinMessage(err), stdout, stderr)) - performanceTest([]string{"--version"}, "", StateVersionTotalSamples, StateVersionMaxTime, suite.Suite, ts) + performanceTest([]string{"--version"}, "", StateVersionTotalSamples, StateVersionMaxTime, false, suite.Suite, ts) } func TestPerformanceIntegrationTestSuite(t *testing.T) { suite.Run(t, new(PerformanceIntegrationTestSuite)) } -func performanceTest(commands []string, expect string, samples int, maxTime time.Duration, suite tagsuite.Suite, ts *e2e.Session) time.Duration { +func performanceTest(commands []string, expect string, samples int, maxTime time.Duration, verbose bool, suite tagsuite.Suite, ts *e2e.Session) time.Duration { rx := regexp.MustCompile(`Profiling: main took .*\((\d+)\)`) var firstEntry, firstLogs string times := []time.Duration{} var total time.Duration for x := 0; x < samples+1; x++ { - cp := ts.SpawnWithOpts( - e2e.WithArgs(commands...), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_UPDATES=true", "ACTIVESTATE_PROFILE=true")) + opts := []e2e.SpawnOptSetter{ + e2e.OptArgs(commands...), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_UPDATES=true", "ACTIVESTATE_PROFILE=true"), + } + termtestLogs := &bytes.Buffer{} + if verbose { + opts = append(opts, e2e.OptTermTest(func(o *termtest.Opts) error { + o.Logger = log.New(termtestLogs, "TermTest: ", log.LstdFlags|log.Lshortfile) + return nil + })) + } + cp := ts.SpawnWithOpts(opts...) if expect != "" { cp.Expect(expect) } cp.ExpectExitCode(0) - v := rx.FindStringSubmatch(cp.Snapshot()) + logs, err := io.ReadAll(termtestLogs) + suite.NoError(err) + v := rx.FindStringSubmatch(cp.Output()) if len(v) < 2 { - suite.T().Fatalf("Could not find '%s' in output: %s", rx.String(), cp.Snapshot()) + suite.T().Fatalf("Could not find '%s' in output:\n%s\n\ntermtest logs:\n%s", rx.String(), cp.Output(), logs) } durMS, err := strconv.Atoi(v[1]) suite.Require().NoError(err) dur := time.Millisecond * time.Duration(durMS) if firstEntry == "" { - firstEntry = cp.Snapshot() - firstLogs = ts.DebugLogs() + firstEntry = cp.Output() + firstLogs = ts.DebugLogsDump() } if x == 0 { // Skip the first one as this one will always be slower due to having to wait for state-svc or sourcing a runtime diff --git a/test/integration/pjfile_int_test.go b/test/integration/pjfile_int_test.go index 1abc0eef1b..51c803c603 100644 --- a/test/integration/pjfile_int_test.go +++ b/test/integration/pjfile_int_test.go @@ -30,8 +30,7 @@ languages: `)) cp := ts.SpawnWithOpts( - e2e.WithArgs("scripts"), - e2e.AppendEnv("VERBOSE=true"), + e2e.OptArgs("scripts"), ) cp.ExpectExitCode(1) } diff --git a/test/integration/platforms_int_test.go b/test/integration/platforms_int_test.go index 393fd60ae9..7d1dc6dd52 100644 --- a/test/integration/platforms_int_test.go +++ b/test/integration/platforms_int_test.go @@ -91,7 +91,7 @@ func (suite *PlatformsIntegrationTestSuite) TestPlatforms_addRemove() { cp = ts.Spawn("platforms") cp.ExpectExitCode(0) - output := cp.TrimmedSnapshot() + output := cp.Output() if strings.Contains(output, "Windows") { suite.T().Fatal("Windows platform should not be present after removal") } @@ -127,7 +127,7 @@ func (suite *PlatformsIntegrationTestSuite) TestPlatforms_addRemoveLatest() { cp = ts.Spawn("platforms") cp.ExpectExitCode(0) - output := cp.TrimmedSnapshot() + output := cp.Output() if strings.Contains(output, "Windows") { suite.T().Fatal("Windows platform should not be present after removal") } diff --git a/test/integration/prepare_int_test.go b/test/integration/prepare_int_test.go index 594f4c4f98..fec3affb7e 100644 --- a/test/integration/prepare_int_test.go +++ b/test/integration/prepare_int_test.go @@ -7,6 +7,10 @@ import ( "path/filepath" "runtime" "testing" + "time" + + "github.com/ActiveState/termtest" + "github.com/stretchr/testify/suite" svcApp "github.com/ActiveState/cli/cmd/state-svc/app" svcAutostart "github.com/ActiveState/cli/cmd/state-svc/autostart" @@ -22,7 +26,6 @@ import ( "github.com/ActiveState/cli/internal/testhelpers/tagsuite" "github.com/ActiveState/cli/pkg/platform/runtime/setup" rt "github.com/ActiveState/cli/pkg/platform/runtime/target" - "github.com/stretchr/testify/suite" ) type PrepareIntegrationTestSuite struct { @@ -47,9 +50,9 @@ func (suite *PrepareIntegrationTestSuite) TestPrepare() { suite.Require().NoError(err) cp := ts.SpawnWithOpts( - e2e.WithArgs("_prepare"), - e2e.AppendEnv(fmt.Sprintf("%s=%s", constants.AutostartPathOverrideEnvVarName, autostartDir)), - // e2e.AppendEnv(fmt.Sprintf("ACTIVESTATE_CLI_CONFIGDIR=%s", ts.Dirs.Work)), + e2e.OptArgs("_prepare"), + e2e.OptAppendEnv(fmt.Sprintf("%s=%s", constants.AutostartPathOverrideEnvVarName, autostartDir)), + // e2e.OptAppendEnv(fmt.Sprintf("ACTIVESTATE_CLI_CONFIGDIR=%s", ts.Dirs.Work)), ) cp.ExpectExitCode(0) @@ -124,12 +127,12 @@ func (suite *PrepareIntegrationTestSuite) TestResetExecutors() { defer ts.Close() cp := ts.SpawnWithOpts( - e2e.WithArgs("activate", "ActiveState-CLI/small-python", "--path", ts.Dirs.Work, "--default"), + e2e.OptArgs("activate", "ActiveState-CLI/small-python", "--path", ts.Dirs.Work, "--default"), ) - cp.ExpectLongString("This project will always be available for use") + cp.Expect("This project will always be available for use") cp.Expect("Downloading") cp.Expect("Installing") - cp.Expect("Activated") + cp.Expect("Activated", termtest.OptExpectTimeout(120*time.Second)) cp.SendLine("exit") cp.ExpectExitCode(0) @@ -161,7 +164,7 @@ func (suite *PrepareIntegrationTestSuite) TestResetExecutors() { err = os.RemoveAll(projectExecDir) cp = ts.Spawn("activate") - cp.Expect("Activated") + cp.Expect("Activated", termtest.OptExpectTimeout(120*time.Second)) cp.SendLine("which python3") cp.SendLine("python3 --version") cp.Expect("ActiveState") diff --git a/test/integration/progress_int_test.go b/test/integration/progress_int_test.go index 6778a2a42c..7f772287bb 100644 --- a/test/integration/progress_int_test.go +++ b/test/integration/progress_int_test.go @@ -19,17 +19,17 @@ func (suite *ProgressIntegrationTestSuite) TestProgress() { defer ts.Close() cp := ts.SpawnWithOpts( - e2e.WithArgs("checkout", "ActiveState-CLI/small-python"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("checkout", "ActiveState-CLI/small-python"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.Expect(locale.T("setup_runtime")) cp.Expect("Checked out") - suite.Assert().NotContains(cp.TrimmedSnapshot(), "...") + suite.Assert().NotContains(cp.Output(), "...") cp.ExpectExitCode(0) cp = ts.SpawnWithOpts( - e2e.WithArgs("checkout", "ActiveState-CLI/small-python", "small-python2", "--non-interactive"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("checkout", "ActiveState-CLI/small-python", "small-python2", "--non-interactive"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.Expect(locale.T("setup_runtime")) cp.Expect("...") diff --git a/test/integration/projects_int_test.go b/test/integration/projects_int_test.go index 2fb110d8c1..c514f65b57 100644 --- a/test/integration/projects_int_test.go +++ b/test/integration/projects_int_test.go @@ -21,35 +21,35 @@ func (suite *ProjectsIntegrationTestSuite) TestProjects() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.SpawnWithOpts(e2e.WithArgs("checkout", "ActiveState-CLI/small-python")) + cp := ts.SpawnWithOpts(e2e.OptArgs("checkout", "ActiveState-CLI/small-python")) cp.ExpectExitCode(0) - cp = ts.SpawnWithOpts(e2e.WithArgs("checkout", "ActiveState-CLI/Python3")) + cp = ts.SpawnWithOpts(e2e.OptArgs("checkout", "ActiveState-CLI/Python3")) cp.ExpectExitCode(0) // Verify local checkouts and executables are grouped together under projects. - cp = ts.SpawnWithOpts(e2e.WithArgs("projects")) + cp = ts.SpawnWithOpts(e2e.OptArgs("projects")) cp.Expect("Python3") cp.Expect("Local Checkout") if runtime.GOOS != "windows" { - cp.ExpectLongString(ts.Dirs.Work) + cp.Expect(ts.Dirs.Work) } else { // Windows uses the long path here. longPath, _ := fileutils.GetLongPathName(ts.Dirs.Work) - cp.ExpectLongString(longPath) + cp.Expect(longPath) } cp.Expect("Executables") - cp.ExpectLongString(ts.Dirs.Cache) + cp.Expect(ts.Dirs.Cache) cp.Expect("small-python") cp.Expect("Local Checkout") if runtime.GOOS != "windows" { - cp.ExpectLongString(ts.Dirs.Work) + cp.Expect(ts.Dirs.Work) } else { // Windows uses the long path here. longPath, _ := fileutils.GetLongPathName(ts.Dirs.Work) - cp.ExpectLongString(longPath) + cp.Expect(longPath) } cp.Expect("Executables") - cp.ExpectLongString(ts.Dirs.Cache) + cp.Expect(ts.Dirs.Cache) cp.ExpectExitCode(0) } @@ -74,7 +74,7 @@ func (suite *ProjectsIntegrationTestSuite) TestJSON() { cp.Expect(`[{`) cp.Expect(`}]`) cp.ExpectExitCode(0) - //AssertValidJSON(suite.T(), cp) // list is too large to fit in terminal snapshot + // AssertValidJSON(suite.T(), cp) // list is too large to fit in terminal snapshot } func (suite *ProjectsIntegrationTestSuite) TestEdit_Name() { @@ -95,7 +95,7 @@ func (suite *ProjectsIntegrationTestSuite) TestEdit_Name() { // If the checkout failed, it's probably because the project name was changed // in a previous run of this test. Try again with the new name. - if strings.Contains(cp.TrimmedSnapshot(), "Could not checkout project") { + if strings.Contains(cp.Output(), "Could not checkout project") { cp = ts.Spawn("checkout", fmt.Sprintf("ActiveState-CLI/%s", newName)) originalName = newName newName = originalName @@ -108,7 +108,7 @@ func (suite *ProjectsIntegrationTestSuite) TestEdit_Name() { cp = ts.Spawn("projects", "edit", fmt.Sprintf("ActiveState-CLI/%s", originalName), "--name", newName) cp.Expect("You are about to edit") - cp.Send("y") + cp.SendLine("y") cp.Expect("Project edited successfully") cp.ExpectExitCode(0) @@ -120,7 +120,7 @@ func (suite *ProjectsIntegrationTestSuite) TestEdit_Name() { // Change name back to original cp = ts.Spawn("projects", "edit", fmt.Sprintf("ActiveState-CLI/%s", newName), "--name", originalName) cp.Expect("You are about to edit") - cp.Send("y") + cp.SendLine("y") cp.Expect("Project edited successfully") cp.ExpectExitCode(0) @@ -141,7 +141,7 @@ func (suite *ProjectsIntegrationTestSuite) TestEdit_Visibility() { cp := ts.Spawn("projects", "edit", namespace, "--visibility", "private") cp.Expect("You are about to edit") - cp.Send("y") + cp.SendLine("y") cp.Expect("Project edited successfully") cp.ExpectExitCode(0) @@ -155,7 +155,7 @@ func (suite *ProjectsIntegrationTestSuite) TestEdit_Visibility() { cp = ts.Spawn("projects", "edit", namespace, "--visibility", "public") cp.Expect("You are about to edit") - cp.Send("y") + cp.SendLine("y") cp.Expect("Project edited successfully") cp.ExpectExitCode(0) } @@ -172,7 +172,7 @@ func (suite *ProjectsIntegrationTestSuite) TestMove() { cp.Expect("You are about to move") cp.Expect("ActiveState-CLI/small-python") cp.Expect("ActiveState-CLI") - cp.Expect("Continue?") + cp.Expect("Continue? (y/N)") cp.SendLine("n") cp.Expect("aborted") cp.ExpectExitCode(0) diff --git a/test/integration/pull_int_test.go b/test/integration/pull_int_test.go index e3d23eef6e..b4ff02e38d 100644 --- a/test/integration/pull_int_test.go +++ b/test/integration/pull_int_test.go @@ -27,7 +27,8 @@ func (suite *PullIntegrationTestSuite) TestPull() { ts.PrepareProject("ActiveState-CLI/Python3", "") cp := ts.Spawn("pull") - cp.ExpectLongString("Operating on project ActiveState-CLI/Python3") + cp.Expect("Operating on project") + cp.Expect("ActiveState-CLI/Python3") cp.Expect("activestate.yaml has been updated") cp.ExpectExitCode(0) @@ -49,7 +50,7 @@ func (suite *PullIntegrationTestSuite) TestPullSetProject() { // update to related project cp := ts.Spawn("pull", "--set-project", "ActiveState-CLI/small-python-fork") - cp.ExpectLongString("you may lose changes to your project") + cp.Expect("Are you sure you want to do this? (y/N)") cp.SendLine("n") cp.Expect("Pull aborted by user") cp.ExpectNotExitCode(0) @@ -67,7 +68,7 @@ func (suite *PullIntegrationTestSuite) TestPullSetProjectUnrelated() { ts.PrepareProject("ActiveState-CLI/small-python", "9733d11a-dfb3-41de-a37a-843b7c421db4") cp := ts.Spawn("pull", "--set-project", "ActiveState-CLI/Python3") - cp.ExpectLongString("you may lose changes to your project") + cp.Expect("Are you sure you want to do this? (y/N)") cp.SendLine("n") cp.Expect("Pull aborted by user") cp.ExpectNotExitCode(0) @@ -95,12 +96,12 @@ func (suite *PullIntegrationTestSuite) TestPull_Merge() { ts.LoginAsPersistentUser() - cp := ts.SpawnWithOpts(e2e.WithArgs("push"), e2e.WithWorkDirectory(wd)) - cp.ExpectLongString("Your project has new changes available") + cp := ts.SpawnWithOpts(e2e.OptArgs("push"), e2e.OptWD(wd)) + cp.Expect("Your project has new changes available") cp.ExpectExitCode(1) - cp = ts.SpawnWithOpts(e2e.WithArgs("pull"), e2e.WithWorkDirectory(wd)) - cp.ExpectLongString("Merging history") + cp = ts.SpawnWithOpts(e2e.OptArgs("pull"), e2e.OptWD(wd)) + cp.Expect("Merging history") cp.ExpectExitCode(0) exe := ts.ExecutablePath() @@ -109,7 +110,7 @@ func (suite *PullIntegrationTestSuite) TestPull_Merge() { exe = filepath.ToSlash(exe) } cp = ts.SpawnCmd("bash", "-c", fmt.Sprintf("cd %s && %s history | head -n 10", wd, exe)) - cp.ExpectLongString("Merged") + cp.Expect("Merged") cp.ExpectExitCode(0) } @@ -122,7 +123,7 @@ func (suite *PullIntegrationTestSuite) TestPull_RestoreNamespace() { // Attempt to update to unrelated project. cp := ts.Spawn("pull", "--non-interactive", "--set-project", "ActiveState-CLI/Python3") - cp.ExpectLongString("Could not detect common parent") + cp.Expect("Could not detect common parent") cp.ExpectNotExitCode(0) // Verify namespace is unchanged. @@ -144,8 +145,8 @@ func (suite *PullIntegrationTestSuite) TestMergeBuildScript() { ts.LoginAsPersistentUser() cp = ts.SpawnWithOpts( - e2e.WithArgs("install", "requests"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("install", "requests"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.Expect("Package added") cp.ExpectExitCode(0) diff --git a/test/integration/push_int_test.go b/test/integration/push_int_test.go index f61c869a59..6b85f2bf2a 100644 --- a/test/integration/push_int_test.go +++ b/test/integration/push_int_test.go @@ -8,6 +8,9 @@ import ( "testing" "time" + "github.com/ActiveState/termtest" + "github.com/stretchr/testify/suite" + "github.com/ActiveState/cli/internal/constants" "github.com/ActiveState/cli/internal/fileutils" "github.com/ActiveState/cli/internal/strutils" @@ -16,7 +19,6 @@ import ( "github.com/ActiveState/cli/pkg/localcommit" "github.com/ActiveState/cli/pkg/project" "github.com/ActiveState/cli/pkg/projectfile" - "github.com/stretchr/testify/suite" ) type PushIntegrationTestSuite struct { @@ -61,7 +63,7 @@ func (suite *PushIntegrationTestSuite) TestInitAndPush() { namespace, wd, ) - cp.ExpectLongString("successfully initialized") + cp.Expect("successfully initialized") cp.ExpectExitCode(0) ts.NotifyProjectCreated(suite.username, pname.String()) @@ -80,13 +82,13 @@ func (suite *PushIntegrationTestSuite) TestInitAndPush() { cp = ts.Spawn(tagsuite.Auth, "logout") cp.ExpectExitCode(0) - cp = ts.SpawnWithOpts(e2e.WithArgs("install", suite.extraPackage), e2e.WithWorkDirectory(wd)) + cp = ts.SpawnWithOpts(e2e.OptArgs("install", suite.extraPackage), e2e.OptWD(wd)) switch runtime.GOOS { case "darwin": - cp.ExpectRe("added|being built", 60*time.Second) // while cold storage is off + cp.ExpectRe("added|being built", termtest.OptExpectTimeout(60*time.Second)) // while cold storage is off cp.Wait() default: - cp.Expect("added", 60*time.Second) + cp.Expect("added", termtest.OptExpectTimeout(60*time.Second)) cp.ExpectExitCode(0) } @@ -98,13 +100,17 @@ func (suite *PushIntegrationTestSuite) TestInitAndPush() { ts.LoginAsPersistentUser() - cp = ts.SpawnWithOpts(e2e.WithArgs("push", namespace), e2e.WithWorkDirectory(wd)) + cp = ts.SpawnWithOpts(e2e.OptArgs("push", namespace), e2e.OptWD(wd)) cp.Expect("Pushing to project") cp.ExpectExitCode(0) } // Test pushing to a new project from a headless commit func (suite *PushIntegrationTestSuite) TestPush_HeadlessConvert_NewProject() { + if runtime.GOOS == "windows" { + suite.T().Skip("Skipped on Windows for now because SendKeyDown() doesnt work (regardless of bash/cmd)") + } + suite.OnlyRunForTags(tagsuite.Push) ts := e2e.New(suite.T(), false) defer ts.Close() @@ -112,15 +118,15 @@ func (suite *PushIntegrationTestSuite) TestPush_HeadlessConvert_NewProject() { pname := strutils.UUID() namespace := fmt.Sprintf("%s/%s", suite.username, pname) - cp := ts.SpawnWithOpts(e2e.WithArgs("install", suite.extraPackage)) + cp := ts.SpawnWithOpts(e2e.OptArgs("install", suite.extraPackage)) - cp.ExpectLongString("An activestate.yaml has been created", time.Second*40) + cp.Expect("An activestate.yaml has been created", termtest.OptExpectTimeout(time.Second*40)) switch runtime.GOOS { case "darwin": - cp.ExpectRe("added|being built", 60*time.Second) // while cold storage is off + cp.ExpectRe("added|being built", termtest.OptExpectTimeout(60*time.Second)) // while cold storage is off cp.Wait() default: - cp.Expect("added", 60*time.Second) + cp.Expect("added", termtest.OptExpectTimeout(60*time.Second)) cp.ExpectExitCode(0) } @@ -131,13 +137,13 @@ func (suite *PushIntegrationTestSuite) TestPush_HeadlessConvert_NewProject() { suite.FailNow("project field should be headless but isn't: " + pjfile.Project) } - cp = ts.SpawnWithOpts(e2e.WithArgs("push")) - cp.ExpectLongString("Who would you like the owner of this project to be?") - cp.Send("") - cp.ExpectLongString("What would you like the name of this project to be?") - cp.SendUnterminated(string([]byte{0033, '[', 'B'})) // move cursor down, and then press enter + cp = ts.SpawnWithOpts(e2e.OptArgs("push")) + cp.Expect("Who would you like the owner of this project to be?") + cp.SendEnter() + cp.Expect("What would you like the name of this project to be?") + cp.SendKeyDown() cp.Expect("> Other") - cp.Send("") + cp.SendEnter() cp.Expect(">") cp.SendLine(pname.String()) cp.Expect("Project created") @@ -153,25 +159,29 @@ func (suite *PushIntegrationTestSuite) TestPush_HeadlessConvert_NewProject() { // Test pushing without permission, and choosing to create a new project func (suite *PushIntegrationTestSuite) TestPush_NoPermission_NewProject() { + if runtime.GOOS == "windows" { + suite.T().Skip("Skipped on Windows for now because SendKeyDown() doesnt work (regardless of bash/cmd)") + } + suite.OnlyRunForTags(tagsuite.Push) ts := e2e.New(suite.T(), false) defer ts.Close() username, _ := ts.CreateNewUser() pname := strutils.UUID() - cp := ts.SpawnWithOpts(e2e.WithArgs("activate", suite.baseProject, "--path", ts.Dirs.Work)) - cp.Expect("Activated", 40*time.Second) - cp.WaitForInput(10 * time.Second) + cp := ts.SpawnWithOpts(e2e.OptArgs("activate", suite.baseProject, "--path", ts.Dirs.Work)) + cp.Expect("Activated", termtest.OptExpectTimeout(40*time.Second)) + cp.ExpectInput(termtest.OptExpectTimeout(10 * time.Second)) cp.SendLine("exit") cp.ExpectExitCode(0) - cp = ts.SpawnWithOpts(e2e.WithArgs("install", suite.extraPackage)) + cp = ts.SpawnWithOpts(e2e.OptArgs("install", suite.extraPackage)) switch runtime.GOOS { case "darwin": - cp.ExpectRe("added|being built", 60*time.Second) // while cold storage is off + cp.ExpectRe("added|being built", termtest.OptExpectTimeout(60*time.Second)) // while cold storage is off cp.Wait() default: - cp.Expect("added", 60*time.Second) + cp.Expect("added", termtest.OptExpectTimeout(60*time.Second)) cp.ExpectExitCode(0) } @@ -180,15 +190,16 @@ func (suite *PushIntegrationTestSuite) TestPush_NoPermission_NewProject() { suite.Require().NoError(err) suite.Require().Contains(pjfile.Project, suite.baseProject) - cp = ts.SpawnWithOpts(e2e.WithArgs("push")) + cp = ts.SpawnWithOpts(e2e.OptArgs("push")) cp.Expect("not authorized") - cp.Send("y") - cp.ExpectLongString("Who would you like the owner of this project to be?") - cp.Send("") - cp.ExpectLongString("What would you like the name of this project to be?") - cp.SendUnterminated(string([]byte{0033, '[', 'B'})) // move cursor down, and then press enter + cp.Expect("(y/N)") + cp.SendLine("y") + cp.Expect("Who would you like the owner of this project to be?") + cp.SendEnter() + cp.Expect("What would you like the name of this project to be?") + cp.SendKeyDown() cp.Expect("> Other") - cp.Send("") + cp.SendEnter() cp.Expect(">") cp.SendLine(pname.String()) cp.Expect("Project created") @@ -211,13 +222,13 @@ func (suite *PushIntegrationTestSuite) TestCarlisle() { wd := filepath.Join(ts.Dirs.Work, namespace) cp := ts.SpawnWithOpts( - e2e.WithArgs( + e2e.OptArgs( "activate", suite.baseProject, "--path", wd), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) // The activestate.yaml on Windows runs custom activation to set shortcuts and file associations. - cp.Expect("Activated") + cp.Expect("Activated", termtest.OptExpectTimeout(120*time.Second)) cp.SendLine("exit") cp.ExpectExitCode(0) @@ -226,16 +237,16 @@ func (suite *PushIntegrationTestSuite) TestCarlisle() { cp.ExpectExitCode(0) // anonymous commit - cp = ts.SpawnWithOpts(e2e.WithArgs( + cp = ts.SpawnWithOpts(e2e.OptArgs( "install", suite.extraPackage), - e2e.WithWorkDirectory(wd), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false")) + e2e.OptWD(wd), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false")) switch runtime.GOOS { case "darwin": - cp.ExpectRe("added|being built", 60*time.Second) // while cold storage is off + cp.ExpectRe("added|being built", termtest.OptExpectTimeout(60*time.Second)) // while cold storage is off cp.Wait() default: - cp.Expect("added", 60*time.Second) + cp.Expect("added", termtest.OptExpectTimeout(60*time.Second)) cp.ExpectExitCode(0) } @@ -245,9 +256,9 @@ func (suite *PushIntegrationTestSuite) TestCarlisle() { ts.LoginAsPersistentUser() - cp = ts.SpawnWithOpts(e2e.WithArgs("push", namespace), e2e.WithWorkDirectory(wd)) - cp.ExpectLongString("You are about to create the project") - cp.Send("y") + cp = ts.SpawnWithOpts(e2e.OptArgs("push", namespace), e2e.OptWD(wd)) + cp.Expect("continue? (Y/n)") + cp.SendLine("y") cp.Expect("Project created") cp.ExpectExitCode(0) ts.NotifyProjectCreated(suite.username, pname.String()) @@ -268,8 +279,8 @@ func (suite *PushIntegrationTestSuite) TestPush_Outdated() { suite.Require().NoError(fileutils.WriteFile(commitIdFile, []byte(unPushedCommit))) ts.LoginAsPersistentUser() - cp := ts.SpawnWithOpts(e2e.WithArgs("push"), e2e.WithWorkDirectory(wd)) - cp.ExpectLongString("Your project has new changes available") + cp := ts.SpawnWithOpts(e2e.OptArgs("push"), e2e.OptWD(wd)) + cp.Expect("Your project has new changes available") cp.ExpectExitCode(1) } diff --git a/test/integration/refresh_int_test.go b/test/integration/refresh_int_test.go index 76be31a0cc..f4a75ffb78 100644 --- a/test/integration/refresh_int_test.go +++ b/test/integration/refresh_int_test.go @@ -21,37 +21,37 @@ func (suite *RefreshIntegrationTestSuite) TestRefresh() { suite.PrepareActiveStateYAML(ts, "ActiveState-CLI/Branches", "main", "35af7414-b44b-4fd7-aa93-2ecad337ed2b") cp := ts.SpawnWithOpts( - e2e.WithArgs("refresh"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("refresh"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.Expect("Setting Up Runtime") cp.Expect("Runtime updated") cp.ExpectExitCode(0) cp = ts.SpawnWithOpts( - e2e.WithArgs("exec", "--", "python3", "-c", "import requests"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("exec", "--", "python3", "-c", "import requests"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.Expect("ModuleNotFoundError") cp.ExpectExitCode(1) suite.PrepareActiveStateYAML(ts, "ActiveState-CLI/Branches", "secondbranch", "46c83477-d580-43e2-a0c6-f5d3677517f1") cp = ts.SpawnWithOpts( - e2e.WithArgs("refresh"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("refresh"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.Expect("Setting Up Runtime") cp.Expect("Runtime updated") cp.ExpectExitCode(0) cp = ts.SpawnWithOpts( - e2e.WithArgs("exec", "--", "python3", "-c", "import requests"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("exec", "--", "python3", "-c", "import requests"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.ExpectExitCode(0) cp = ts.Spawn("refresh") - suite.Assert().NotContains(cp.TrimmedSnapshot(), "Setting Up Runtime", "Unchanged runtime should not refresh") + suite.Assert().NotContains(cp.Output(), "Setting Up Runtime", "Unchanged runtime should not refresh") cp.Expect("Runtime updated") cp.ExpectExitCode(0) } @@ -68,7 +68,7 @@ func (suite *RefreshIntegrationTestSuite) TestJSON() { cp.Expect(`"path":`) cp.Expect(`"executables":`) cp.ExpectExitCode(0) - //AssertValidJSON(suite.T(), cp) // cannot assert here due to "Skipping runtime setup" notice + // AssertValidJSON(suite.T(), cp) // cannot assert here due to "Skipping runtime setup" notice } func (suite *RefreshIntegrationTestSuite) PrepareActiveStateYAML(ts *e2e.Session, namespace, branch, commitID string) { diff --git a/test/integration/remote_installer_int_test.go b/test/integration/remote_installer_int_test.go index 17b66bde18..b12fbcf2a3 100644 --- a/test/integration/remote_installer_int_test.go +++ b/test/integration/remote_installer_int_test.go @@ -60,25 +60,25 @@ func (suite *RemoteInstallIntegrationTestSuite) TestInstall() { cp := ts.SpawnCmdWithOpts( suite.remoteInstallerExe, - e2e.WithArgs(args...), - e2e.AppendEnv(constants.InstallPathOverrideEnvVarName+"="+installPath), - e2e.AppendEnv(fmt.Sprintf("%s=%s", constants.AppInstallDirOverrideEnvVarName, appInstallDir)), + e2e.OptArgs(args...), + e2e.OptAppendEnv(constants.InstallPathOverrideEnvVarName+"="+installPath), + e2e.OptAppendEnv(fmt.Sprintf("%s=%s", constants.AppInstallDirOverrideEnvVarName, appInstallDir)), ) cp.Expect("Terms of Service") - cp.SendLine("y") + cp.SendLine("Y") cp.Expect("Installing") cp.Expect("Installation Complete") cp.Expect("Press ENTER to exit") - cp.SendLine("") + cp.SendEnter() cp.ExpectExitCode(0) suite.Require().FileExists(stateExePath) cp = ts.SpawnCmdWithOpts( stateExePath, - e2e.WithArgs("--version"), - e2e.AppendEnv(constants.InstallPathOverrideEnvVarName+"="+installPath), + e2e.OptArgs("--version"), + e2e.OptAppendEnv(constants.InstallPathOverrideEnvVarName+"="+installPath), ) if tt.Version != "" { cp.Expect("Version " + tt.Version) diff --git a/test/integration/revert_int_test.go b/test/integration/revert_int_test.go index 546b149ffb..f5ac49eef2 100644 --- a/test/integration/revert_int_test.go +++ b/test/integration/revert_int_test.go @@ -21,7 +21,7 @@ func (suite *RevertIntegrationTestSuite) TestRevert() { ts.LoginAsPersistentUser() namespace := "ActiveState-CLI/Revert" - cp := ts.SpawnWithOpts(e2e.WithArgs("checkout", namespace)) + cp := ts.SpawnWithOpts(e2e.OptArgs("checkout", namespace)) cp.Expect("Skipping runtime setup") cp.Expect("Checked out project") cp.ExpectExitCode(0) @@ -29,18 +29,18 @@ func (suite *RevertIntegrationTestSuite) TestRevert() { // Revert the commit that added urllib3. commitID := "1f4f4f7d-7883-400e-b2ad-a5803c018ecd" - cp = ts.SpawnWithOpts(e2e.WithArgs("revert", commitID), e2e.WithWorkDirectory(wd)) - cp.ExpectLongString(fmt.Sprintf("Operating on project %s", namespace)) - cp.SendLine("Y") + cp = ts.SpawnWithOpts(e2e.OptArgs("revert", commitID), e2e.OptWD(wd)) + cp.Expect(fmt.Sprintf("Operating on project %s", namespace)) cp.Expect("You are about to revert the following commit:") cp.Expect(commitID) + cp.SendLine("y") cp.Expect("Successfully reverted commit:") cp.ExpectExitCode(0) // Verify the commit history has both the new revert commit and all prior history. cp = ts.SpawnWithOpts( - e2e.WithArgs("history"), - e2e.WithWorkDirectory(wd), + e2e.OptArgs("history"), + e2e.OptWD(wd), ) cp.Expect("Revert commit " + commitID) cp.Expect("- urllib3") @@ -50,16 +50,16 @@ func (suite *RevertIntegrationTestSuite) TestRevert() { // Verify that argparse still exists (it was not reverted along with urllib3). cp = ts.SpawnWithOpts( - e2e.WithArgs("shell", "Revert"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("shell", "Revert"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) - cp.WaitForInput() + cp.ExpectInput() cp.SendLine("python3") cp.Expect("3.9.15") cp.SendLine("import urllib3") cp.Expect("No module named 'urllib3'") cp.SendLine("import argparse") - suite.Assert().NotContains(cp.TrimmedSnapshot(), "No module named 'argparse'") + suite.Assert().NotContains(cp.Output(), "No module named 'argparse'") cp.SendLine("exit()") // exit python3 cp.SendLine("exit") // exit state shell cp.ExpectExitCode(0) @@ -71,7 +71,7 @@ func (suite *RevertIntegrationTestSuite) TestRevert_failsOnCommitNotInHistory() defer ts.Close() namespace := "ActiveState-CLI/small-python" - cp := ts.SpawnWithOpts(e2e.WithArgs("checkout", namespace)) + cp := ts.SpawnWithOpts(e2e.OptArgs("checkout", namespace)) cp.Expect("Skipping runtime setup") cp.Expect("Checked out project") cp.ExpectExitCode(0) @@ -79,11 +79,11 @@ func (suite *RevertIntegrationTestSuite) TestRevert_failsOnCommitNotInHistory() // valid commit id not from project commitID := "cb9b1aab-8e40-4a1d-8ad6-5ea112da40f1" // from Perl-5.32 - cp = ts.SpawnWithOpts(e2e.WithArgs("revert", commitID), e2e.WithWorkDirectory(wd)) - cp.ExpectLongString(fmt.Sprintf("Operating on project %s", namespace)) + cp = ts.SpawnWithOpts(e2e.OptArgs("revert", commitID), e2e.OptWD(wd)) + cp.Expect(fmt.Sprintf("Operating on project %s", namespace)) cp.SendLine("Y") cp.Expect(commitID) - cp.ExpectLongString("The commit being reverted is not within the current commit's history") + cp.Expect("The commit being reverted is not within the current commit's history") cp.ExpectNotExitCode(0) } @@ -94,7 +94,7 @@ func (suite *RevertIntegrationTestSuite) TestRevertTo() { ts.LoginAsPersistentUser() namespace := "ActiveState-CLI/Revert" - cp := ts.SpawnWithOpts(e2e.WithArgs("checkout", namespace)) + cp := ts.SpawnWithOpts(e2e.OptArgs("checkout", namespace)) cp.Expect("Skipping runtime setup") cp.Expect("Checked out project") cp.ExpectExitCode(0) @@ -102,8 +102,8 @@ func (suite *RevertIntegrationTestSuite) TestRevertTo() { // Revert the commit that added urllib3. commitID := "1f4f4f7d-7883-400e-b2ad-a5803c018ecd" - cp = ts.SpawnWithOpts(e2e.WithArgs("revert", "--to", commitID), e2e.WithWorkDirectory(wd)) - cp.ExpectLongString(fmt.Sprintf("Operating on project %s", namespace)) + cp = ts.SpawnWithOpts(e2e.OptArgs("revert", "--to", commitID), e2e.OptWD(wd)) + cp.Expect(fmt.Sprintf("Operating on project %s", namespace)) cp.SendLine("Y") cp.Expect("You are about to revert to the following commit:") cp.Expect(commitID) @@ -112,8 +112,8 @@ func (suite *RevertIntegrationTestSuite) TestRevertTo() { // Verify the commit history has both the new revert commit and all prior history. cp = ts.SpawnWithOpts( - e2e.WithArgs("history"), - e2e.WithWorkDirectory(wd), + e2e.OptArgs("history"), + e2e.OptWD(wd), ) cp.Expect("Reverting to commit " + commitID) cp.Expect("- argparse") // effectively reverting previous commit @@ -128,7 +128,7 @@ func (suite *RevertIntegrationTestSuite) TestRevertTo_failsOnCommitNotInHistory( defer ts.Close() namespace := "ActiveState-CLI/small-python" - cp := ts.SpawnWithOpts(e2e.WithArgs("checkout", namespace)) + cp := ts.SpawnWithOpts(e2e.OptArgs("checkout", namespace)) cp.Expect("Skipping runtime setup") cp.Expect("Checked out project") cp.ExpectExitCode(0) @@ -136,8 +136,8 @@ func (suite *RevertIntegrationTestSuite) TestRevertTo_failsOnCommitNotInHistory( // valid commit id not from project commitID := "cb9b1aab-8e40-4a1d-8ad6-5ea112da40f1" // from Perl-5.32 - cp = ts.SpawnWithOpts(e2e.WithArgs("revert", "--to", commitID), e2e.WithWorkDirectory(wd)) - cp.ExpectLongString(fmt.Sprintf("Operating on project %s", namespace)) + cp = ts.SpawnWithOpts(e2e.OptArgs("revert", "--to", commitID), e2e.OptWD(wd)) + cp.Expect(fmt.Sprintf("Operating on project %s", namespace)) cp.SendLine("Y") cp.Expect(commitID) cp.Expect("The target commit is not") @@ -157,7 +157,7 @@ func (suite *RevertIntegrationTestSuite) TestJSON() { cp = ts.Spawn("revert", "--to", "1f4f4f7d-7883-400e-b2ad-a5803c018ecd", "-o", "json") cp.Expect(`{"current_commit_id":`) cp.ExpectExitCode(0) - //AssertValidJSON(suite.T(), cp) // cannot assert here due to "Skipping runtime setup" notice + // AssertValidJSON(suite.T(), cp) // cannot assert here due to "Skipping runtime setup" notice } func TestRevertIntegrationTestSuite(t *testing.T) { diff --git a/test/integration/run_int_test.go b/test/integration/run_int_test.go index 4d9fdcf1d5..b3e4b24855 100644 --- a/test/integration/run_int_test.go +++ b/test/integration/run_int_test.go @@ -83,13 +83,13 @@ func (suite *RunIntegrationTestSuite) TearDownTest() { projectfile.Reset() } -func (suite *RunIntegrationTestSuite) expectTerminateBatchJob(cp *termtest.ConsoleProcess) { +func (suite *RunIntegrationTestSuite) expectTerminateBatchJob(cp *e2e.SpawnedCmd) { if runtime.GOOS == "windows" { // send N to "Terminate batch job (Y/N)" question cp.Expect("Terminate batch job") time.Sleep(200 * time.Millisecond) - cp.Send("N") - cp.Expect("N", 500*time.Millisecond) + cp.SendLine("N") + cp.Expect("N", termtest.OptExpectTimeout(500*time.Millisecond)) } } @@ -107,25 +107,26 @@ func (suite *RunIntegrationTestSuite) TestInActivatedEnv() { suite.createProjectFile(ts, 3) cp := ts.Spawn("activate") - cp.Expect("Activated") - cp.WaitForInput(10 * time.Second) + cp.Expect("Activated", termtest.OptExpectTimeout(120*time.Second)) + cp.ExpectInput(termtest.OptExpectTimeout(10 * time.Second)) - cp.SendLine(fmt.Sprintf("%s run testMultipleLanguages", cp.Executable())) - cp.ExpectLongString("Operating on project ActiveState-CLI/Python3") + cp.SendLine(fmt.Sprintf("%s run testMultipleLanguages", ts.Exe)) + cp.Expect("Operating on project") + cp.Expect("ActiveState-CLI/Python3") cp.Expect("3") cp.SendLine(fmt.Sprintf("%s run test-interrupt", cp.Executable())) - cp.Expect("Start of script", 5*time.Second) + cp.Expect("Start of script", termtest.OptExpectTimeout(5*time.Second)) cp.SendCtrlC() - cp.Expect("received interrupt", 3*time.Second) - cp.Expect("After first sleep or interrupt", 2*time.Second) + cp.Expect("received interrupt", termtest.OptExpectTimeout(3*time.Second)) + cp.Expect("After first sleep or interrupt", termtest.OptExpectTimeout(2*time.Second)) cp.SendCtrlC() suite.expectTerminateBatchJob(cp) cp.SendLine("exit 0") cp.ExpectExitCode(0) suite.Require().NotContains( - cp.TrimmedSnapshot(), "not printed after second interrupt", + cp.Output(), "not printed after second interrupt", ) } @@ -142,9 +143,9 @@ func (suite *RunIntegrationTestSuite) TestScriptBashSubshell() { suite.createProjectFile(ts, 3) - cp := ts.SpawnWithOpts(e2e.WithArgs("activate"), e2e.AppendEnv("SHELL=bash")) - cp.Expect("Activated") - cp.WaitForInput(10 * time.Second) + cp := ts.SpawnWithOpts(e2e.OptArgs("activate"), e2e.OptAppendEnv("SHELL=bash")) + cp.Expect("Activated", termtest.OptExpectTimeout(120*time.Second)) + cp.ExpectInput(termtest.OptExpectTimeout(10 * time.Second)) cp.SendLine("helloWorld") cp.Expect("Hello World!") @@ -168,8 +169,8 @@ func (suite *RunIntegrationTestSuite) TestOneInterrupt() { // interrupt the first (very long) sleep cp.SendCtrlC() - cp.Expect("received interrupt", 3*time.Second) - cp.Expect("After first sleep or interrupt", 2*time.Second) + cp.Expect("received interrupt", termtest.OptExpectTimeout(3*time.Second)) + cp.Expect("After first sleep or interrupt", termtest.OptExpectTimeout(2*time.Second)) cp.Expect("After second sleep") suite.expectTerminateBatchJob(cp) cp.ExpectExitCode(0) @@ -190,13 +191,13 @@ func (suite *RunIntegrationTestSuite) TestTwoInterrupts() { cp := ts.Spawn("run", "test-interrupt") cp.Expect("Start of script") cp.SendCtrlC() - cp.Expect("received interrupt", 3*time.Second) - cp.Expect("After first sleep or interrupt", 2*time.Second) + cp.Expect("received interrupt", termtest.OptExpectTimeout(3*time.Second)) + cp.Expect("After first sleep or interrupt", termtest.OptExpectTimeout(2*time.Second)) cp.SendCtrlC() suite.expectTerminateBatchJob(cp) cp.ExpectExitCode(123) suite.Require().NotContains( - cp.TrimmedSnapshot(), "not printed after second interrupt", + cp.Output(), "not printed after second interrupt", ) } @@ -229,14 +230,14 @@ func (suite *RunIntegrationTestSuite) TestRun_Unauthenticated() { suite.createProjectFile(ts, 2) - cp := ts.SpawnWithOpts(e2e.WithArgs("activate")) + cp := ts.SpawnWithOpts(e2e.OptArgs("activate")) cp.Expect("Skipping runtime setup") cp.Expect("Activated") - cp.WaitForInput(10 * time.Second) + cp.ExpectInput(termtest.OptExpectTimeout(10 * time.Second)) cp.SendLine(fmt.Sprintf("%s run testMultipleLanguages", cp.Executable())) cp.Expect("2") - cp.WaitForInput(120 * time.Second) + cp.ExpectInput(termtest.OptExpectTimeout(120 * time.Second)) cp.SendLine("exit") cp.ExpectExitCode(0) @@ -250,8 +251,8 @@ func (suite *RunIntegrationTestSuite) TestRun_DeprecatedLackingLanguage() { suite.createProjectFile(ts, 3) cp := ts.Spawn("run", "helloWorld") - cp.Expect("Deprecation Warning", 5*time.Second) - cp.Expect("Hello", 5*time.Second) + cp.Expect("Deprecation Warning", termtest.OptExpectTimeout(5*time.Second)) + cp.Expect("Hello", termtest.OptExpectTimeout(5*time.Second)) } func (suite *RunIntegrationTestSuite) TestRun_BadLanguage() { @@ -274,7 +275,7 @@ func (suite *RunIntegrationTestSuite) TestRun_BadLanguage() { suite.Require().NoError(err, "extra config is appended") cp := ts.Spawn("run", "badLanguage") - cp.Expect("The language for this script is not supported", 5*time.Second) + cp.Expect("The language for this script is not supported", termtest.OptExpectTimeout(5*time.Second)) } func (suite *RunIntegrationTestSuite) TestRun_Perl_Variable() { @@ -289,14 +290,14 @@ func (suite *RunIntegrationTestSuite) TestRun_Perl_Variable() { ts.PrepareProject("ActiveState-CLI/Perl-5.32", "a4762408-def6-41e4-b709-4cb548765005") cp := ts.SpawnWithOpts( - e2e.WithArgs("activate"), - e2e.AppendEnv( + e2e.OptArgs("activate"), + e2e.OptAppendEnv( "ACTIVESTATE_CLI_DISABLE_RUNTIME=false", "PERL_VERSION=does_not_exist", ), ) - cp.Expect("Activated") - cp.WaitForInput(10 * time.Second) + cp.Expect("Activated", termtest.OptExpectTimeout(120*time.Second)) + cp.ExpectInput(termtest.OptExpectTimeout(10 * time.Second)) cp.SendLine("perl -MEnglish -e 'print $PERL_VERSION'") cp.Expect("v5.32.0") diff --git a/test/integration/runtime_int_test.go b/test/integration/runtime_int_test.go index 8f1ba0de1a..2ea4d22cbb 100644 --- a/test/integration/runtime_int_test.go +++ b/test/integration/runtime_int_test.go @@ -86,8 +86,8 @@ func (suite *RuntimeIntegrationTestSuite) TestInterruptSetup() { defer ts.Close() cp := ts.SpawnWithOpts( - e2e.WithArgs("checkout", "ActiveState-CLI/test-interrupt-small-python#863c45e2-3626-49b6-893c-c15e85a17241", "."), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("checkout", "ActiveState-CLI/test-interrupt-small-python#863c45e2-3626-49b6-893c-c15e85a17241", "."), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.Expect("Checked out project") @@ -98,8 +98,8 @@ func (suite *RuntimeIntegrationTestSuite) TestInterruptSetup() { cp.ExpectExitCode(0) cp = ts.SpawnWithOpts( - e2e.WithArgs("pull"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false", + e2e.OptArgs("pull"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false", "ACTIVESTATE_CLI_RUNTIME_SETUP_WAIT=true"), ) time.Sleep(30 * time.Second) diff --git a/test/integration/scripts_int_test.go b/test/integration/scripts_int_test.go index 61d0bcfc98..cdfb194bbb 100644 --- a/test/integration/scripts_int_test.go +++ b/test/integration/scripts_int_test.go @@ -43,7 +43,7 @@ func (suite *ScriptsIntegrationTestSuite) TestRunInheritEnv() { ts := e2e.New(suite.T(), false) suite.setupConfigFile(ts) - cp := ts.SpawnWithOpts(e2e.WithArgs("run", "testenv"), e2e.AppendEnv("I_SHOULD_EXIST=I_SURE_DO_EXIST")) + cp := ts.SpawnWithOpts(e2e.OptArgs("run", "testenv"), e2e.OptAppendEnv("I_SHOULD_EXIST=I_SURE_DO_EXIST")) cp.Expect("I_SURE_DO_EXIST") cp.ExpectExitCode(0) } diff --git a/test/integration/secrets_int_test.go b/test/integration/secrets_int_test.go index b0d1b3e6d0..219e342870 100644 --- a/test/integration/secrets_int_test.go +++ b/test/integration/secrets_int_test.go @@ -37,20 +37,23 @@ func (suite *SecretsIntegrationTestSuite) TestSecrets_JSON() { ts.LoginAsPersistentUser() cp := ts.Spawn("secrets", "set", "project.test-secret", "test-value") - cp.ExpectLongString("Operating on project cli-integration-tests/Python3") + cp.Expect("Operating on project") + cp.Expect("cli-integration-tests/Python3") cp.ExpectExitCode(0) cp = ts.Spawn("secrets", "get", "project.test-secret", "--output", "json") cp.ExpectExitCode(0) - suite.Equal(string(expected), cp.TrimmedSnapshot()) + suite.Equal(string(expected), cp.StrippedSnapshot()) cp = ts.Spawn("secrets", "sync") - cp.ExpectLongString("Operating on project cli-integration-tests/Python3") + cp.Expect("Operating on project") + cp.Expect("cli-integration-tests/Python3") cp.Expect("Successfully synchronized") cp.ExpectExitCode(0) cp = ts.Spawn("secrets") - cp.ExpectLongString("Operating on project cli-integration-tests/Python3") + cp.Expect("Operating on project") + cp.Expect("cli-integration-tests/Python3") cp.Expect("Name") cp.Expect("project") cp.Expect("Description") @@ -59,7 +62,7 @@ func (suite *SecretsIntegrationTestSuite) TestSecrets_JSON() { cp.ExpectExitCode(0) } -func (suite *SecretsIntegrationTestSuite) TestSecrect_Expand() { +func (suite *SecretsIntegrationTestSuite) TestSecret_Expand() { suite.OnlyRunForTags(tagsuite.Secrets, tagsuite.JSON) ts := e2e.New(suite.T(), false) defer ts.Close() @@ -83,11 +86,13 @@ scripts: ts.PrepareActiveStateYAML(asyData) cp := ts.Spawn("secrets", "set", "project.project-secret", "project-value") - cp.ExpectLongString("Operating on project ActiveState-CLI/secrets-test") + cp.Expect("Operating on project") + cp.Expect("ActiveState-CLI/secrets-test") cp.ExpectExitCode(0) cp = ts.Spawn("secrets", "set", "user.user-secret", "user-value") - cp.ExpectLongString("Operating on project ActiveState-CLI/secrets-test") + cp.Expect("Operating on project") + cp.Expect("ActiveState-CLI/secrets-test") cp.ExpectExitCode(0) cp = ts.Spawn("run", "project-secret") diff --git a/test/integration/shared_int_test.go b/test/integration/shared_int_test.go index b5e1ecf969..71f4331f1d 100644 --- a/test/integration/shared_int_test.go +++ b/test/integration/shared_int_test.go @@ -7,9 +7,11 @@ import ( "strings" "testing" - "github.com/ActiveState/cli/internal/logging" - "github.com/ActiveState/termtest" "github.com/stretchr/testify/assert" + + "github.com/ActiveState/cli/internal/locale" + "github.com/ActiveState/cli/internal/logging" + "github.com/ActiveState/cli/internal/testhelpers/e2e" ) func init() { @@ -21,19 +23,20 @@ func init() { // AssertValidJSON asserts that the previous command emitted valid JSON and did not attempt to emit // any non-JSON/structured output. // This should only be called after a command has executed and all output is available. -func AssertValidJSON(t *testing.T, cp *termtest.ConsoleProcess) { - snapshot := cp.TrimmedSnapshot() +func AssertValidJSON(t *testing.T, cp *e2e.SpawnedCmd) { + output := cp.StrippedSnapshot() + output = strings.TrimPrefix(output, locale.T("notice_runtime_disabled")) if runtime.GOOS != "windows" { - assert.True(t, json.Valid([]byte(snapshot)), "The command produced invalid JSON/structured output:\n"+snapshot) + assert.True(t, json.Valid([]byte(output)), "The command produced invalid JSON/structured output:\n"+output) } else { // Windows can trim the last byte for some reason. assert.True( t, - json.Valid([]byte(snapshot)) || json.Valid([]byte(snapshot+"}")) || json.Valid([]byte(snapshot+"]")), - "The command produced invalid JSON/structured output:\n"+snapshot, + json.Valid([]byte(output)) || json.Valid([]byte(output+"}")) || json.Valid([]byte(output+"]")), + "The command produced invalid JSON/structured output:\n"+output, ) } - if strings.Contains(snapshot, `"errors":[`) { - assert.NotContains(t, snapshot, `output not supported`, "The command attempted to emit non-JSON/structured output:\n"+snapshot) + if strings.Contains(output, `"errors":[`) { + assert.NotContains(t, output, `output not supported`, "The command attempted to emit non-JSON/structured output:\n"+output) } } diff --git a/test/integration/shell_int_test.go b/test/integration/shell_int_test.go index ae8777e46a..b44592da04 100644 --- a/test/integration/shell_int_test.go +++ b/test/integration/shell_int_test.go @@ -6,6 +6,10 @@ import ( "path/filepath" "runtime" "testing" + "time" + + "github.com/ActiveState/termtest" + "github.com/stretchr/testify/suite" "github.com/ActiveState/cli/internal/config" "github.com/ActiveState/cli/internal/constants" @@ -16,7 +20,6 @@ import ( "github.com/ActiveState/cli/internal/subshell/zsh" "github.com/ActiveState/cli/internal/testhelpers/e2e" "github.com/ActiveState/cli/internal/testhelpers/tagsuite" - "github.com/stretchr/testify/suite" ) type ShellIntegrationTestSuite struct { @@ -30,7 +33,7 @@ func (suite *ShellIntegrationTestSuite) TestShell() { defer ts.Close() cp := ts.SpawnWithOpts( - e2e.WithArgs("checkout", "ActiveState-CLI/small-python"), + e2e.OptArgs("checkout", "ActiveState-CLI/small-python"), ) cp.Expect("Checked out project") cp.ExpectExitCode(0) @@ -38,10 +41,10 @@ func (suite *ShellIntegrationTestSuite) TestShell() { args := []string{"small-python", "ActiveState-CLI/small-python"} for _, arg := range args { cp := ts.SpawnWithOpts( - e2e.WithArgs("shell", arg), + e2e.OptArgs("shell", arg), ) cp.Expect("Activated") - cp.WaitForInput() + cp.ExpectInput() cp.SendLine("python3 --version") cp.Expect("Python 3") @@ -60,14 +63,14 @@ func (suite *ShellIntegrationTestSuite) TestShell() { suite.Require().NoError(err) cp = ts.Spawn("shell", projectName) - cp.ExpectLongString(fmt.Sprintf("Could not load project %s from path: %s", projectName, projectDir)) + cp.Expect(fmt.Sprintf("Could not load project %s from path: %s", projectName, projectDir)) } // Check for project not checked out. args = []string{"Python-3.9", "ActiveState-CLI/Python-3.9"} for _, arg := range args { cp := ts.SpawnWithOpts( - e2e.WithArgs("shell", arg), + e2e.OptArgs("shell", arg), ) cp.Expect("Cannot find the Python-3.9 project") cp.ExpectExitCode(1) @@ -81,24 +84,24 @@ func (suite *ShellIntegrationTestSuite) TestDefaultShell() { defer ts.Close() // Checkout. - cp := ts.SpawnWithOpts(e2e.WithArgs("checkout", "ActiveState-CLI/small-python")) + cp := ts.SpawnWithOpts(e2e.OptArgs("checkout", "ActiveState-CLI/small-python")) cp.Expect("Skipping runtime setup") cp.Expect("Checked out project") cp.ExpectExitCode(0) // Use. cp = ts.SpawnWithOpts( - e2e.WithArgs("use", "ActiveState-CLI/small-python"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("use", "ActiveState-CLI/small-python"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) - cp.Expect("Switched to project") + cp.Expect("Switched to project", termtest.OptExpectTimeout(120*time.Second)) cp.ExpectExitCode(0) cp = ts.SpawnWithOpts( - e2e.WithArgs("shell"), + e2e.OptArgs("shell"), ) cp.Expect("Activated") - cp.WaitForInput() + cp.ExpectInput() cp.SendLine("exit") cp.ExpectExitCode(0) } @@ -110,19 +113,19 @@ func (suite *ShellIntegrationTestSuite) TestCwdShell() { defer ts.Close() cp := ts.SpawnWithOpts( - e2e.WithArgs("activate", "ActiveState-CLI/small-python"), + e2e.OptArgs("activate", "ActiveState-CLI/small-python"), ) cp.Expect("Activated") - cp.WaitForInput() + cp.ExpectInput() cp.SendLine("exit") cp.ExpectExitCode(0) cp = ts.SpawnWithOpts( - e2e.WithArgs("shell"), - e2e.WithWorkDirectory(filepath.Join(ts.Dirs.Work, "small-python")), + e2e.OptArgs("shell"), + e2e.OptWD(filepath.Join(ts.Dirs.Work, "small-python")), ) cp.Expect("Activated") - cp.WaitForInput() + cp.ExpectInput() cp.SendLine("exit") cp.ExpectExitCode(0) } @@ -134,10 +137,10 @@ func (suite *ShellIntegrationTestSuite) TestCd() { defer ts.Close() cp := ts.SpawnWithOpts( - e2e.WithArgs("activate", "ActiveState-CLI/small-python"), + e2e.OptArgs("activate", "ActiveState-CLI/small-python"), ) cp.Expect("Activated") - cp.WaitForInput() + cp.ExpectInput() cp.SendLine("exit") cp.ExpectExitCode(0) @@ -146,25 +149,25 @@ func (suite *ShellIntegrationTestSuite) TestCd() { suite.Require().NoError(err) cp = ts.SpawnWithOpts( - e2e.WithArgs("shell", "ActiveState-CLI/small-python"), - e2e.WithWorkDirectory(subdir), + e2e.OptArgs("shell", "ActiveState-CLI/small-python"), + e2e.OptWD(subdir), ) cp.Expect("Activated") - cp.WaitForInput() + cp.ExpectInput() if runtime.GOOS != "windows" { cp.SendLine("pwd") } else { cp.SendLine("echo %cd%") } - cp.ExpectLongString(subdir) + cp.Expect(subdir) cp.SendLine("exit") cp = ts.SpawnWithOpts( - e2e.WithArgs("shell", "ActiveState-CLI/small-python", "--cd"), - e2e.WithWorkDirectory(subdir), + e2e.OptArgs("shell", "ActiveState-CLI/small-python", "--cd"), + e2e.OptWD(subdir), ) cp.Expect("Activated") - cp.WaitForInput() + cp.ExpectInput() if runtime.GOOS != "windows" { cp.SendLine("ls") } else { @@ -182,14 +185,14 @@ func (suite *ShellIntegrationTestSuite) TestDefaultNoLongerExists() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.SpawnWithOpts(e2e.WithArgs("checkout", "ActiveState-CLI/Python3")) + cp := ts.SpawnWithOpts(e2e.OptArgs("checkout", "ActiveState-CLI/Python3")) cp.Expect("Skipping runtime setup") cp.Expect("Checked out project") cp.ExpectExitCode(0) cp = ts.SpawnWithOpts( - e2e.WithArgs("use", "ActiveState-CLI/Python3"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("use", "ActiveState-CLI/Python3"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.Expect("Switched to project") cp.ExpectExitCode(0) @@ -197,7 +200,7 @@ func (suite *ShellIntegrationTestSuite) TestDefaultNoLongerExists() { err := os.RemoveAll(filepath.Join(ts.Dirs.Work, "Python3")) suite.Require().NoError(err) - cp = ts.SpawnWithOpts(e2e.WithArgs("shell")) + cp = ts.SpawnWithOpts(e2e.OptArgs("shell")) cp.Expect("Cannot find your project") cp.ExpectExitCode(1) } @@ -225,9 +228,9 @@ func (suite *ShellIntegrationTestSuite) TestUseShellUpdates() { } cp = ts.SpawnWithOpts( - e2e.WithArgs("use", "ActiveState-CLI/Python3"), - e2e.AppendEnv("SHELL=bash"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("use", "ActiveState-CLI/Python3"), + e2e.OptAppendEnv("SHELL=bash"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.Expect("Switched to project") cp.ExpectExitCode(0) @@ -249,7 +252,7 @@ func (suite *ShellIntegrationTestSuite) TestJSON() { defer ts.Close() cp := ts.Spawn("shell", "--output", "json") - cp.ExpectLongString(`"error":"This command does not support the json output format`) + cp.Expect(`"error":"This command does not support the json output format`) cp.ExpectExitCode(0) AssertValidJSON(suite.T(), cp) } @@ -315,14 +318,14 @@ func (suite *ShellIntegrationTestSuite) TestNestedShellNotification() { cp.ExpectExitCode(0) cp = ts.SpawnWithOpts( - e2e.WithArgs("shell", "small-python"), - e2e.AppendEnv(env...)) - cp.Expect("Activated") - suite.Assert().NotContains(cp.TrimmedSnapshot(), "State Tool is operating on project") + e2e.OptArgs("shell", "small-python"), + e2e.OptAppendEnv(env...)) + cp.Expect("Activated", termtest.OptExpectTimeout(120*time.Second)) + suite.Assert().NotContains(cp.Output(), "State Tool is operating on project") cp.SendLine(fmt.Sprintf(`export HOME="%s"`, ts.Dirs.HomeDir)) // some shells do not forward this cp.SendLine(ss.Binary()) // platform-specific shell (zsh on macOS, bash on Linux, etc.) - cp.ExpectLongString("State Tool is operating on project ActiveState-CLI/small-python") + cp.Expect("State Tool is operating on project ActiveState-CLI/small-python") cp.SendLine("exit") // subshell within a subshell cp.SendLine("exit") cp.ExpectExitCode(0) @@ -341,11 +344,11 @@ func (suite *ShellIntegrationTestSuite) TestRuby() { cp.ExpectExitCode(0) cp = ts.SpawnWithOpts( - e2e.WithArgs("shell", "Ruby-3.2.2"), - e2e.AppendEnv(constants.DisableRuntime+"=false"), + e2e.OptArgs("shell", "Ruby-3.2.2"), + e2e.OptAppendEnv(constants.DisableRuntime+"=false"), ) cp.Expect("Activated") - cp.WaitForInput() + cp.ExpectInput() cp.SendLine("ruby -v") cp.Expect("3.2.2") cp.Expect("ActiveState") diff --git a/test/integration/shells_int_test.go b/test/integration/shells_int_test.go index fa0955c44d..f8de612c83 100644 --- a/test/integration/shells_int_test.go +++ b/test/integration/shells_int_test.go @@ -4,10 +4,13 @@ import ( "fmt" "runtime" "testing" + "time" + + "github.com/ActiveState/termtest" + "github.com/stretchr/testify/suite" "github.com/ActiveState/cli/internal/testhelpers/e2e" "github.com/ActiveState/cli/internal/testhelpers/tagsuite" - "github.com/stretchr/testify/suite" ) type ShellsIntegrationTestSuite struct { @@ -32,16 +35,18 @@ func (suite *ShellsIntegrationTestSuite) TestShells() { // Checkout the first instance. It doesn't matter which shell is used. cp := ts.SpawnWithOpts( - e2e.WithArgs("checkout", "ActiveState-CLI/small-python"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("checkout", "ActiveState-CLI/small-python"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.Expect("Checked out project") cp.ExpectExitCode(0) for _, shell := range shells { suite.T().Run(fmt.Sprintf("using_%s", shell), func(t *testing.T) { + ts.SetT(t) + // Run the checkout in a particular shell. - cp := ts.SpawnShellWithOpts(shell) + cp = ts.SpawnShellWithOpts(shell) cp.SendLine(e2e.QuoteCommand(shell, ts.ExecutablePath(), "checkout", "ActiveState-CLI/small-python", string(shell))) cp.Expect("Checked out project") cp.SendLine("exit") @@ -51,13 +56,13 @@ func (suite *ShellsIntegrationTestSuite) TestShells() { // There are 2 or more instances checked out, so we should get a prompt in whichever shell we // use. - cp = ts.SpawnShellWithOpts(shell, e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false")) + cp = ts.SpawnShellWithOpts(shell, e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false")) cp.SendLine(e2e.QuoteCommand(shell, ts.ExecutablePath(), "shell", "small-python")) cp.Expect("Multiple project paths") // Just pick the first one and verify the selection prompt works. - cp.SendLine("") - cp.Expect("Activated") + cp.SendEnter() + cp.Expect("Activated", termtest.OptExpectTimeout(120*time.Second)) // Verify that the command prompt contains the right info, except for tcsh, whose prompt does // not behave like other shells'. diff --git a/test/integration/show_int_test.go b/test/integration/show_int_test.go index 323e4599b7..3ee2b5581d 100644 --- a/test/integration/show_int_test.go +++ b/test/integration/show_int_test.go @@ -25,10 +25,10 @@ func (suite *ShowIntegrationTestSuite) TestShow() { suite.PrepareProject(ts) cp := ts.SpawnWithOpts( - e2e.WithArgs("activate"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("activate"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) - cp.WaitForInput() + cp.ExpectInput() cp = ts.Spawn("show") cp.Expect(`Name`) @@ -38,13 +38,13 @@ func (suite *ShowIntegrationTestSuite) TestShow() { cp.Expect(`Namespace`) cp.Expect(`cli-integration-tests/Show`) cp.Expect(`Location`) - cp.ExpectLongString(ts.Dirs.Work) + cp.Expect(ts.Dirs.Work) cp.Expect(`Executables`) - cp.ExpectLongString(ts.Dirs.Cache) + cp.Expect(ts.Dirs.Cache) cp.Expect(`Visibility`) cp.Expect(`Public`) cp.Expect(`Latest Commit`) - cp.ExpectLongString(`d5d84598-fc2e-4a45-b075-a845e587b5bf`) + cp.Expect(`d5d84598-fc2e-4a45-b075-a845e587b5bf`) cp.Expect(`Events`) cp.Expect(`• FIRST_INSTALL`) cp.Expect(`• AFTER_UPDATE`) @@ -65,7 +65,7 @@ func (suite *ShowIntegrationTestSuite) TestShowWithoutBranch() { ts.PrepareProject("cli-integration-tests/Show", "e8f3b07b-502f-4763-83c1-763b9b952e18") - cp := ts.SpawnWithOpts(e2e.WithArgs("show")) + cp := ts.SpawnWithOpts(e2e.OptArgs("show")) cp.ExpectExitCode(0) contents, err := fileutils.ReadFile(filepath.Join(ts.Dirs.Work, constants.ConfigFileName)) diff --git a/test/integration/softlimit_int_test.go b/test/integration/softlimit_int_test.go index 3a09caa7b7..b730a6487d 100644 --- a/test/integration/softlimit_int_test.go +++ b/test/integration/softlimit_int_test.go @@ -2,7 +2,9 @@ package integration import ( "testing" + "time" + "github.com/ActiveState/termtest" "github.com/stretchr/testify/suite" "github.com/ActiveState/cli/internal/constants" @@ -28,35 +30,35 @@ func (suite *SoftLimitIntegrationTestSuite) TestCheckout() { ts.LoginAsPersistentUser() cp := ts.SpawnWithOpts( - e2e.WithArgs("checkout", "ActiveState-CLI/small-python", "."), - e2e.AppendEnv(constants.RuntimeUsageOverrideEnvVarName+"=999"), - e2e.AppendEnv(constants.DisableRuntime+"=true"), // We're testing the usage, not the runtime + e2e.OptArgs("checkout", "ActiveState-CLI/small-python", "."), + e2e.OptAppendEnv(constants.RuntimeUsageOverrideEnvVarName+"=999"), + e2e.OptAppendEnv(constants.DisableRuntime+"=true"), // We're testing the usage, not the runtime ) cp.Expect("You've reached your runtime limit") cp.ExpectExitCode(0) suite.Run("activate", func() { cp := ts.SpawnWithOpts( - e2e.WithArgs("activate"), - e2e.AppendEnv(constants.RuntimeUsageOverrideEnvVarName+"=999"), - e2e.AppendEnv(constants.DisableRuntime+"=true"), + e2e.OptArgs("activate"), + e2e.OptAppendEnv(constants.RuntimeUsageOverrideEnvVarName+"=999"), + e2e.OptAppendEnv(constants.DisableRuntime+"=true"), ) cp.Expect("You've reached your runtime limit") - cp.Expect("Activated") - cp.WaitForInput() + cp.Expect("Activated", termtest.OptExpectTimeout(120*time.Second)) + cp.ExpectInput() cp.SendLine("exit 0") cp.ExpectExitCode(0) }) suite.Run("shell", func() { cp := ts.SpawnWithOpts( - e2e.WithArgs("shell"), - e2e.AppendEnv(constants.RuntimeUsageOverrideEnvVarName+"=999"), - e2e.AppendEnv(constants.DisableRuntime+"=true"), + e2e.OptArgs("shell"), + e2e.OptAppendEnv(constants.RuntimeUsageOverrideEnvVarName+"=999"), + e2e.OptAppendEnv(constants.DisableRuntime+"=true"), ) cp.Expect("You've reached your runtime limit") - cp.Expect("Activated") - cp.WaitForInput() + cp.Expect("Activated", termtest.OptExpectTimeout(120*time.Second)) + cp.ExpectInput() cp.SendLine("exit 0") cp.ExpectExitCode(0) }) diff --git a/test/integration/switch_int_test.go b/test/integration/switch_int_test.go index f39853371d..7508c78de8 100644 --- a/test/integration/switch_int_test.go +++ b/test/integration/switch_int_test.go @@ -34,9 +34,10 @@ func (suite *SwitchIntegrationTestSuite) TestSwitch_Branch() { mainBranchCommitID, err := localcommit.Get(ts.Dirs.Work) suite.Require().NoError(err) - cp := ts.SpawnWithOpts(e2e.WithArgs("switch", "secondbranch")) - cp.ExpectLongString("Operating on project ActiveState-CLI/Branches") - cp.ExpectLongString("Successfully switched to branch:") + cp := ts.SpawnWithOpts(e2e.OptArgs("switch", "secondbranch")) + cp.Expect("Operating on project") + cp.Expect("ActiveState-CLI/Branches") + cp.Expect("Successfully switched to branch:") if runtime.GOOS != "windows" { cp.ExpectExitCode(0) } @@ -67,8 +68,8 @@ func (suite *SwitchIntegrationTestSuite) TestSwitch_CommitID() { originalCommitID, err := localcommit.Get(ts.Dirs.Work) suite.Require().NoError(err) - cp := ts.SpawnWithOpts(e2e.WithArgs("switch", "efce7c7a-c61a-4b04-bb00-f8e7edfd247f")) - cp.ExpectLongString("Successfully switched to commit:") + cp := ts.SpawnWithOpts(e2e.OptArgs("switch", "efce7c7a-c61a-4b04-bb00-f8e7edfd247f")) + cp.Expect("Successfully switched to commit:") if runtime.GOOS != "windows" { cp.ExpectExitCode(0) } @@ -97,8 +98,8 @@ func (suite *SwitchIntegrationTestSuite) TestSwitch_CommitID_NotInHistory() { originalCommitID, err := localcommit.Get(ts.Dirs.Work) suite.Require().NoError(err) - cp := ts.SpawnWithOpts(e2e.WithArgs("switch", "76dff77a-66b9-43e3-90be-dc75917dd661")) - cp.ExpectLongString("Commit does not belong") + cp := ts.SpawnWithOpts(e2e.OptArgs("switch", "76dff77a-66b9-43e3-90be-dc75917dd661")) + cp.Expect("Commit does not belong") if runtime.GOOS != "windows" { cp.ExpectExitCode(1) } @@ -124,7 +125,7 @@ func (suite *SwitchIntegrationTestSuite) TestJSON() { cp = ts.Spawn("switch", "firstbranch", "--output", "json") cp.Expect(`"branch":`) cp.ExpectExitCode(0) - //AssertValidJSON(suite.T(), cp) // cannot assert here due to "Skipping runtime setup" notice + // AssertValidJSON(suite.T(), cp) // cannot assert here due to "Skipping runtime setup" notice } func TestSwitchIntegrationTestSuite(t *testing.T) { diff --git a/test/integration/uninstall_int_test.go b/test/integration/uninstall_int_test.go index 09806337e0..1c0436a9ce 100644 --- a/test/integration/uninstall_int_test.go +++ b/test/integration/uninstall_int_test.go @@ -53,16 +53,16 @@ func (suite *UninstallIntegrationTestSuite) testUninstall(all bool) { err = installation.SaveContext(&installation.Context{InstalledAsAdmin: isAdmin}) suite.NoError(err) - cp := ts.SpawnCmdWithOpts(ts.SvcExe, e2e.WithArgs("start")) + cp := ts.SpawnCmdWithOpts(ts.SvcExe, e2e.OptArgs("start")) cp.ExpectExitCode(0) if all { cp = ts.SpawnWithOpts( - e2e.WithArgs("clean", "uninstall", "--all"), + e2e.OptArgs("clean", "uninstall", "--all"), ) } else { cp = ts.SpawnWithOpts( - e2e.WithArgs("clean", "uninstall"), + e2e.OptArgs("clean", "uninstall"), ) } cp.Expect("You are about to remove") @@ -71,15 +71,15 @@ func (suite *UninstallIntegrationTestSuite) testUninstall(all bool) { } cp.SendLine("y") if runtime.GOOS == "windows" { - cp.ExpectLongString("Deletion of State Tool has been scheduled.") + cp.Expect("Deletion of State Tool has been scheduled.") } else { - cp.ExpectLongString("Successfully removed State Tool and related files") + cp.Expect("Successfully removed State Tool and related files") } cp.ExpectExitCode(0) if runtime.GOOS == "windows" { // Allow time for spawned script to remove directories - time.Sleep(500 * time.Millisecond) + time.Sleep(2000 * time.Millisecond) } if all { diff --git a/test/integration/update_int_test.go b/test/integration/update_int_test.go index cddcf36d00..5b3c8c1df2 100644 --- a/test/integration/update_int_test.go +++ b/test/integration/update_int_test.go @@ -72,11 +72,11 @@ func (suite *UpdateIntegrationTestSuite) versionCompare(ts *e2e.Session, expecte Version string `json:"version"` } - cp := ts.SpawnWithOpts(e2e.WithArgs("--version", "--output=json"), e2e.AppendEnv(suite.env(true, false)...)) + cp := ts.SpawnWithOpts(e2e.OptArgs("--version", "--output=json"), e2e.OptAppendEnv(suite.env(true, false)...)) cp.ExpectExitCode(0) version := versionData{} - out := strings.Trim(cp.TrimmedSnapshot(), "\x00") + out := cp.StrippedSnapshot() json.Unmarshal([]byte(out), &version) matcher(expected, version.Version, fmt.Sprintf("Version could not be matched, output:\n\n%s", out)) @@ -87,11 +87,11 @@ func (suite *UpdateIntegrationTestSuite) branchCompare(ts *e2e.Session, expected Branch string `json:"branch"` } - cp := ts.SpawnWithOpts(e2e.WithArgs("--version", "--output=json"), e2e.AppendEnv(suite.env(true, false)...)) - cp.ExpectExitCode(0, 30*time.Second) + cp := ts.SpawnWithOpts(e2e.OptArgs("--version", "--output=json"), e2e.OptAppendEnv(suite.env(true, false)...)) + cp.ExpectExitCode(0, termtest.OptExpectTimeout(30*time.Second)) branch := branchData{} - out := strings.Trim(cp.TrimmedSnapshot(), "\x00") + out := cp.StrippedSnapshot() json.Unmarshal([]byte(out), &branch) matcher(expected, branch.Branch, fmt.Sprintf("Branch could not be matched, output:\n\n%s", out)) @@ -109,7 +109,7 @@ func (suite *UpdateIntegrationTestSuite) TestUpdateAvailable() { time.Sleep(time.Second * 3) } - cp := ts.SpawnWithOpts(e2e.WithArgs("--version"), e2e.AppendEnv(suite.env(false, true)...)) + cp := ts.SpawnWithOpts(e2e.OptArgs("--version"), e2e.OptAppendEnv(suite.env(false, true)...)) cp.ExpectExitCode(0) if strings.Contains(cp.Snapshot(), search) { @@ -130,14 +130,14 @@ func (suite *UpdateIntegrationTestSuite) TestUpdate() { suite.testUpdate(ts, filepath.Dir(ts.Dirs.Bin)) } -func (suite *UpdateIntegrationTestSuite) testUpdate(ts *e2e.Session, baseDir string, opts ...e2e.SpawnOptions) { +func (suite *UpdateIntegrationTestSuite) testUpdate(ts *e2e.Session, baseDir string, opts ...e2e.SpawnOptSetter) { cfg, err := config.NewCustom(ts.Dirs.Config, singlethread.New(), true) suite.Require().NoError(err) defer cfg.Close() - spawnOpts := []e2e.SpawnOptions{ - e2e.WithArgs("update"), - e2e.AppendEnv(suite.env(false, true)...), + spawnOpts := []e2e.SpawnOptSetter{ + e2e.OptArgs("update"), + e2e.OptAppendEnv(suite.env(false, true)...), } if opts != nil { spawnOpts = append(spawnOpts, opts...) @@ -184,10 +184,10 @@ func (suite *UpdateIntegrationTestSuite) TestUpdate_Repair() { stateExePath := filepath.Join(ts.Dirs.Bin, filepath.Base(ts.Exe)) - spawnOpts := []e2e.SpawnOptions{ - e2e.WithArgs("update"), - e2e.AppendEnv(fmt.Sprintf("%s=%s", constants.OverwriteDefaultInstallationPathEnvVarName, ts.Dirs.Bin)), - e2e.AppendEnv(suite.env(false, true)...), + spawnOpts := []e2e.SpawnOptSetter{ + e2e.OptArgs("update"), + e2e.OptAppendEnv(fmt.Sprintf("%s=%s", constants.OverwriteDefaultInstallationPathEnvVarName, ts.Dirs.Bin)), + e2e.OptAppendEnv(suite.env(false, true)...), } searchA, searchB, found := "Updating State Tool to version", "Installing Update", false @@ -197,7 +197,7 @@ func (suite *UpdateIntegrationTestSuite) TestUpdate_Repair() { } cp := ts.SpawnCmdWithOpts(stateExePath, spawnOpts...) - cp.Wait(time.Minute * 3) + cp.ExpectExitCode(0, termtest.OptExpectTimeout(time.Minute)) snap := cp.Snapshot() if strings.Contains(snap, searchA) && strings.Contains(snap, searchB) { @@ -234,11 +234,11 @@ func (suite *UpdateIntegrationTestSuite) TestUpdateChannel() { env := []string{fmt.Sprintf("%s=%s", constants.OverwriteDefaultInstallationPathEnvVarName, ts.Dirs.Bin)} env = append(env, suite.env(false, false)...) cp := ts.SpawnWithOpts( - e2e.WithArgs(updateArgs...), - e2e.AppendEnv(env...), + e2e.OptArgs(updateArgs...), + e2e.OptAppendEnv(env...), ) cp.Expect("Updating") - cp.ExpectExitCode(0, 1*time.Minute) + cp.ExpectExitCode(0, termtest.OptExpectTimeout(1*time.Minute)) suite.branchCompare(ts, tt.Channel, suite.Equal) }) @@ -288,15 +288,15 @@ func (suite *UpdateIntegrationTestSuite) TestAutoUpdate() { suite.testAutoUpdate(ts, filepath.Dir(ts.Dirs.Bin)) } -func (suite *UpdateIntegrationTestSuite) testAutoUpdate(ts *e2e.Session, baseDir string, opts ...e2e.SpawnOptions) { +func (suite *UpdateIntegrationTestSuite) testAutoUpdate(ts *e2e.Session, baseDir string, opts ...e2e.SpawnOptSetter) { fakeHome := filepath.Join(ts.Dirs.Work, "home") suite.Require().NoError(fileutils.Mkdir(fakeHome)) - spawnOpts := []e2e.SpawnOptions{ - e2e.WithArgs("--version"), - e2e.AppendEnv(suite.env(false, true)...), - e2e.AppendEnv(fmt.Sprintf("HOME=%s", fakeHome)), - e2e.AppendEnv("ACTIVESTATE_TEST_AUTO_UPDATE=true"), + spawnOpts := []e2e.SpawnOptSetter{ + e2e.OptArgs("--version"), + e2e.OptAppendEnv(suite.env(false, true)...), + e2e.OptAppendEnv(fmt.Sprintf("HOME=%s", fakeHome)), + e2e.OptAppendEnv("ACTIVESTATE_TEST_AUTO_UPDATE=true"), } if opts != nil { spawnOpts = append(spawnOpts, opts...) @@ -312,7 +312,7 @@ func (suite *UpdateIntegrationTestSuite) testAutoUpdate(ts *e2e.Session, baseDir } cp := ts.SpawnCmdWithOpts(stateExec, spawnOpts...) - cp.ExpectExitCode(0, time.Minute*1) + cp.ExpectExitCode(0, termtest.OptExpectTimeout(time.Minute)) if strings.Contains(cp.Snapshot(), search) { found = true @@ -324,11 +324,11 @@ func (suite *UpdateIntegrationTestSuite) testAutoUpdate(ts *e2e.Session, baseDir } func (suite *UpdateIntegrationTestSuite) installLatestReleaseVersion(ts *e2e.Session, dir string) { - var cp *termtest.ConsoleProcess + var cp *e2e.SpawnedCmd if runtime.GOOS != "windows" { oneLiner := fmt.Sprintf("sh <(curl -q https://platform.activestate.com/dl/cli/pdli01/install.sh) -f -n -t %s", dir) cp = ts.SpawnCmdWithOpts( - "bash", e2e.WithArgs("-c", oneLiner), + "bash", e2e.OptArgs("-c", oneLiner), ) } else { b, err := httputil.GetDirect("https://platform.activestate.com/dl/cli/pdli01/install.ps1") @@ -337,11 +337,11 @@ func (suite *UpdateIntegrationTestSuite) installLatestReleaseVersion(ts *e2e.Ses ps1File := filepath.Join(ts.Dirs.Work, "install.ps1") suite.Require().NoError(fileutils.WriteFile(ps1File, b)) - cp = ts.SpawnCmdWithOpts("powershell.exe", e2e.WithArgs(ps1File, "-f", "-n", "-t", dir), - e2e.AppendEnv("SHELL="), + cp = ts.SpawnCmdWithOpts("powershell.exe", e2e.OptArgs(ps1File, "-f", "-n", "-t", dir), + e2e.OptAppendEnv("SHELL="), ) } - cp.Expect("Installation Complete", 5*time.Minute) + cp.Expect("Installation Complete", termtest.OptExpectTimeout(5*time.Minute)) stateExec, err := installation.StateExecFromDir(dir) suite.NoError(err) @@ -361,7 +361,7 @@ func (suite *UpdateIntegrationTestSuite) TestAutoUpdateToCurrent() { suite.installLatestReleaseVersion(ts, installDir) - suite.testAutoUpdate(ts, installDir, e2e.AppendEnv(fmt.Sprintf("ACTIVESTATE_CLI_UPDATE_BRANCH=%s", constants.BranchName))) + suite.testAutoUpdate(ts, installDir, e2e.OptAppendEnv(fmt.Sprintf("ACTIVESTATE_CLI_UPDATE_BRANCH=%s", constants.BranchName))) } func (suite *UpdateIntegrationTestSuite) TestUpdateToCurrent() { @@ -379,5 +379,5 @@ func (suite *UpdateIntegrationTestSuite) TestUpdateToCurrent() { suite.installLatestReleaseVersion(ts, installDir) - suite.testUpdate(ts, installDir, e2e.AppendEnv(fmt.Sprintf("ACTIVESTATE_CLI_UPDATE_BRANCH=%s", constants.BranchName))) + suite.testUpdate(ts, installDir, e2e.OptAppendEnv(fmt.Sprintf("ACTIVESTATE_CLI_UPDATE_BRANCH=%s", constants.BranchName))) } diff --git a/test/integration/update_lock_int_test.go b/test/integration/update_lock_int_test.go index e528ff2f2e..889aa8d870 100644 --- a/test/integration/update_lock_int_test.go +++ b/test/integration/update_lock_int_test.go @@ -32,8 +32,8 @@ func (suite *UpdateIntegrationTestSuite) TestLocked() { pjfile.Save(cfg) cp := ts.SpawnWithOpts( - e2e.WithArgs("update", "lock"), - e2e.AppendEnv(suite.env(false, false)...), + e2e.OptArgs("update", "lock"), + e2e.OptAppendEnv(suite.env(false, false)...), ) cp.Expect("Version locked at") @@ -91,8 +91,8 @@ func (suite *UpdateIntegrationTestSuite) TestLockedChannel() { pjfile.Save(cfg) cp := ts.SpawnWithOpts( - e2e.WithArgs("update", "lock", "--set-channel", tt.lock), - e2e.AppendEnv(suite.env(false, false)...), + e2e.OptArgs("update", "lock", "--set-channel", tt.lock), + e2e.OptAppendEnv(suite.env(false, false)...), ) cp.Expect("Version locked at") cp.Expect(tt.expectedChannel + "@") @@ -103,7 +103,7 @@ func (suite *UpdateIntegrationTestSuite) TestLockedChannel() { suite.Contains(string(yamlContents), tt.lock) if tt.expectLockError { - cp = ts.SpawnWithOpts(e2e.WithArgs("--version"), e2e.AppendEnv(suite.env(true, false)...)) + cp = ts.SpawnWithOpts(e2e.OptArgs("--version"), e2e.OptAppendEnv(suite.env(true, false)...)) cp.Expect("This project is locked at State Tool version") cp.ExpectExitCode(1) return @@ -149,15 +149,15 @@ func (suite *UpdateIntegrationTestSuite) TestUpdateLockedConfirmation() { args = append(args, "--non-interactive") } cp := ts.SpawnWithOpts( - e2e.WithArgs(args...), - e2e.AppendEnv(suite.env(true, true)...), + e2e.OptArgs(args...), + e2e.OptAppendEnv(suite.env(true, true)...), ) cp.Expect("sure you want") if tt.Confirm || tt.Forced { - cp.Send("y") + cp.SendLine("y") cp.Expect("Version locked at") } else { - cp.Send("n") + cp.SendLine("n") cp.Expect("Cancelling") } cp.ExpectNotExitCode(0) @@ -182,8 +182,8 @@ func (suite *UpdateIntegrationTestSuite) TestLockUnlock() { pjfile.Save(cfg) cp := ts.SpawnWithOpts( - e2e.WithArgs("update", "lock", "--non-interactive"), - e2e.AppendEnv(suite.env(false, false)...), + e2e.OptArgs("update", "lock", "--non-interactive"), + e2e.OptAppendEnv(suite.env(false, false)...), ) cp.Expect("locked at") @@ -194,8 +194,8 @@ func (suite *UpdateIntegrationTestSuite) TestLockUnlock() { suite.Assert().True(lockRegex.Match(data), "lock info was not written to "+pjfile.Path()) cp = ts.SpawnWithOpts( - e2e.WithArgs("update", "unlock", "-n"), - e2e.AppendEnv(suite.env(false, false)...), + e2e.OptArgs("update", "unlock", "-n"), + e2e.OptAppendEnv(suite.env(false, false)...), ) cp.Expect("unlocked") diff --git a/test/integration/upgen_int_test.go b/test/integration/upgen_int_test.go index 076fc6b294..866b2b4456 100644 --- a/test/integration/upgen_int_test.go +++ b/test/integration/upgen_int_test.go @@ -15,7 +15,6 @@ import ( "github.com/ActiveState/cli/internal/environment" "github.com/ActiveState/cli/internal/testhelpers/e2e" "github.com/ActiveState/cli/internal/testhelpers/tagsuite" - "github.com/ActiveState/termtest" ) type UpdateGenIntegrationTestSuite struct { @@ -46,7 +45,7 @@ func (suite *UpdateGenIntegrationTestSuite) TestUpdateBits() { ts := e2e.New(suite.T(), false) defer ts.Close() - var cp *termtest.ConsoleProcess + var cp *e2e.SpawnedCmd if runtime.GOOS == "windows" { cp = ts.SpawnCmd("powershell.exe", "-nologo", "-noprofile", "-command", diff --git a/test/integration/use_int_test.go b/test/integration/use_int_test.go index be98d86719..ffa1a97d8d 100644 --- a/test/integration/use_int_test.go +++ b/test/integration/use_int_test.go @@ -27,15 +27,15 @@ func (suite *UseIntegrationTestSuite) TestUse() { defer ts.Close() // Checkout. - cp := ts.SpawnWithOpts(e2e.WithArgs("checkout", "ActiveState-CLI/Python3")) + cp := ts.SpawnWithOpts(e2e.OptArgs("checkout", "ActiveState-CLI/Python3")) cp.Expect("Skipping runtime setup") cp.Expect("Checked out project") cp.ExpectExitCode(0) // Use. cp = ts.SpawnWithOpts( - e2e.WithArgs("use", "ActiveState-CLI/Python3"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("use", "ActiveState-CLI/Python3"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.Expect("Switched to project") cp.ExpectExitCode(0) @@ -47,39 +47,39 @@ func (suite *UseIntegrationTestSuite) TestUse() { cp.ExpectExitCode(0) // Checkout another project. - cp = ts.SpawnWithOpts(e2e.WithArgs("checkout", "ActiveState-CLI/Python-3.9")) + cp = ts.SpawnWithOpts(e2e.OptArgs("checkout", "ActiveState-CLI/Python-3.9")) cp.Expect("Skipping runtime setup") cp.Expect("Checked out project") cp.ExpectExitCode(0) // Use it. cp = ts.SpawnWithOpts( - e2e.WithArgs("use", "ActiveState-CLI/Python-3.9"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("use", "ActiveState-CLI/Python-3.9"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.Expect("Switched to project") cp.ExpectExitCode(0) // Verify the new runtime works. - cp = ts.SpawnCmdWithOpts(pythonExe, e2e.WithArgs("--version")) + cp = ts.SpawnCmdWithOpts(pythonExe, e2e.OptArgs("--version")) cp.Expect("Python 3") cp.ExpectExitCode(0) // Switch back using just the project name. cp = ts.SpawnWithOpts( - e2e.WithArgs("use", "Python3"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("use", "Python3"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.Expect("Switched to project") cp.ExpectExitCode(0) // Verify the first runtime is set up correctly and usable. - cp = ts.SpawnCmdWithOpts(pythonExe, e2e.WithArgs("--version")) + cp = ts.SpawnCmdWithOpts(pythonExe, e2e.OptArgs("--version")) cp.Expect("Python 3") cp.ExpectExitCode(0) // Test failure switching to project name that was not checked out. - cp = ts.SpawnWithOpts(e2e.WithArgs("use", "NotCheckedOut")) + cp = ts.SpawnWithOpts(e2e.OptArgs("use", "NotCheckedOut")) cp.Expect("Cannot find the NotCheckedOut project.") cp.ExpectExitCode(1) } @@ -92,15 +92,15 @@ func (suite *UseIntegrationTestSuite) TestUseCwd() { pythonDir := filepath.Join(ts.Dirs.Work, "MyPython3") - cp := ts.SpawnWithOpts(e2e.WithArgs("checkout", "ActiveState-CLI/Python3", pythonDir)) + cp := ts.SpawnWithOpts(e2e.OptArgs("checkout", "ActiveState-CLI/Python3", pythonDir)) cp.Expect("Skipping runtime setup") cp.Expect("Checked out project") cp.ExpectExitCode(0) cp = ts.SpawnWithOpts( - e2e.WithArgs("use"), - e2e.WithWorkDirectory(pythonDir), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("use"), + e2e.OptWD(pythonDir), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.Expect("Switched to project") cp.ExpectExitCode(0) @@ -108,8 +108,8 @@ func (suite *UseIntegrationTestSuite) TestUseCwd() { emptyDir := filepath.Join(ts.Dirs.Work, "EmptyDir") suite.Require().NoError(fileutils.Mkdir(emptyDir)) cp = ts.SpawnWithOpts( - e2e.WithArgs("use"), - e2e.WithWorkDirectory(emptyDir), + e2e.OptArgs("use"), + e2e.OptWD(emptyDir), ) cp.Expect("Unable to use project") cp.ExpectExitCode(1) @@ -124,14 +124,14 @@ func (suite *UseIntegrationTestSuite) TestReset() { suite.SetupRCFile(ts) suite.T().Setenv("ACTIVESTATE_HOME", ts.Dirs.HomeDir) - cp := ts.SpawnWithOpts(e2e.WithArgs("checkout", "ActiveState-CLI/Python3")) + cp := ts.SpawnWithOpts(e2e.OptArgs("checkout", "ActiveState-CLI/Python3")) cp.Expect("Skipping runtime setup") cp.Expect("Checked out project") cp.ExpectExitCode(0) cp = ts.SpawnWithOpts( - e2e.WithArgs("use", "ActiveState-CLI/Python3"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("use", "ActiveState-CLI/Python3"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.Expect("Switched to project") cp.ExpectExitCode(0) @@ -147,20 +147,20 @@ func (suite *UseIntegrationTestSuite) TestReset() { suite.Contains(string(fileutils.ReadFileUnsafe(rcfile)), ts.Dirs.DefaultBin, "PATH does not have your project in it") } - cp = ts.SpawnWithOpts(e2e.WithArgs("use", "reset")) + cp = ts.SpawnWithOpts(e2e.OptArgs("use", "reset")) cp.Expect("Continue?") cp.SendLine("n") cp.Expect("Reset aborted by user") cp.ExpectExitCode(1) - cp = ts.SpawnWithOpts(e2e.WithArgs("use", "reset", "--non-interactive")) + cp = ts.SpawnWithOpts(e2e.OptArgs("use", "reset", "--non-interactive")) cp.Expect("Stopped using your project runtime") cp.Expect("Note you may need to") cp.ExpectExitCode(0) suite.False(fileutils.TargetExists(python3Exe), python3Exe+" still exists") - cp = ts.SpawnWithOpts(e2e.WithArgs("use", "reset")) + cp = ts.SpawnWithOpts(e2e.OptArgs("use", "reset")) cp.Expect("No project to stop using") cp.ExpectExitCode(1) @@ -175,55 +175,55 @@ func (suite *UseIntegrationTestSuite) TestShow() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.SpawnWithOpts(e2e.WithArgs("use", "show")) + cp := ts.SpawnWithOpts(e2e.OptArgs("use", "show")) cp.Expect("No project is being used") cp.ExpectExitCode(1) - cp = ts.SpawnWithOpts(e2e.WithArgs("checkout", "ActiveState-CLI/Python3")) + cp = ts.SpawnWithOpts(e2e.OptArgs("checkout", "ActiveState-CLI/Python3")) cp.Expect("Skipping runtime setup") cp.Expect("Checked out project") cp.ExpectExitCode(0) cp = ts.SpawnWithOpts( - e2e.WithArgs("use", "ActiveState-CLI/Python3"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("use", "ActiveState-CLI/Python3"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.Expect("Switched to project") cp.ExpectExitCode(0) cp = ts.SpawnWithOpts( - e2e.WithArgs("use", "show"), + e2e.OptArgs("use", "show"), ) - cp.ExpectLongString("The active project is ActiveState-CLI/Python3") + cp.Expect("The active project is ActiveState-CLI/Python3") projectDir := filepath.Join(ts.Dirs.Work, "Python3") if runtime.GOOS != "windows" { - cp.ExpectLongString(projectDir) + cp.Expect(projectDir) } else { // Windows uses the long path here. longPath, err := fileutils.GetLongPathName(projectDir) suite.Require().NoError(err) - cp.ExpectLongString(longPath) + cp.Expect(longPath) } - cp.ExpectLongString(ts.Dirs.Cache) + cp.Expect(ts.Dirs.Cache) cp.Expect("exec") cp.ExpectExitCode(0) err := os.RemoveAll(projectDir) suite.Require().NoError(err) - cp = ts.SpawnWithOpts(e2e.WithArgs("use", "show")) - cp.ExpectLongString("Cannot find your project") + cp = ts.SpawnWithOpts(e2e.OptArgs("use", "show")) + cp.Expect("Cannot find your project") // Both Windows and MacOS can run into path comparison issues with symlinks and long paths. if runtime.GOOS == "linux" { - cp.ExpectLongString(fmt.Sprintf("Could not find project at %s", projectDir)) + cp.Expect(fmt.Sprintf("Could not find project at %s", projectDir)) } cp.ExpectExitCode(1) - cp = ts.SpawnWithOpts(e2e.WithArgs("use", "reset", "--non-interactive")) + cp = ts.SpawnWithOpts(e2e.OptArgs("use", "reset", "--non-interactive")) cp.Expect("Stopped using your project runtime") cp.ExpectExitCode(0) - cp = ts.SpawnWithOpts(e2e.WithArgs("use", "show")) + cp = ts.SpawnWithOpts(e2e.OptArgs("use", "show")) cp.Expect("No project is being used") cp.ExpectExitCode(1) } @@ -235,8 +235,8 @@ func (suite *UseIntegrationTestSuite) TestSetupNotice() { defer ts.Close() cp := ts.SpawnWithOpts( - e2e.WithArgs("checkout", "ActiveState-CLI/Python3"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("checkout", "ActiveState-CLI/Python3"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.Expect("Setting Up Runtime") cp.Expect("Checked out project") @@ -245,15 +245,15 @@ func (suite *UseIntegrationTestSuite) TestSetupNotice() { suite.Require().NoError(os.RemoveAll(filepath.Join(ts.Dirs.Work, "Python3"))) // runtime marker still exists cp = ts.SpawnWithOpts( - e2e.WithArgs("checkout", "ActiveState-CLI/Python3#623dadf8-ebf9-4876-bfde-f45afafe5ea8"), + e2e.OptArgs("checkout", "ActiveState-CLI/Python3#623dadf8-ebf9-4876-bfde-f45afafe5ea8"), ) cp.Expect("Skipping runtime setup") cp.Expect("Checked out project") cp.ExpectExitCode(0) cp = ts.SpawnWithOpts( - e2e.WithArgs("use", "Python3"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("use", "Python3"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.Expect("Setting Up Runtime") cp.Expect("Switched to project") @@ -271,8 +271,8 @@ func (suite *UseIntegrationTestSuite) TestJSON() { cp.ExpectExitCode(0) cp = ts.SpawnWithOpts( - e2e.WithArgs("use", "-o", "json"), - e2e.AppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), + e2e.OptArgs("use", "-o", "json"), + e2e.OptAppendEnv("ACTIVESTATE_CLI_DISABLE_RUNTIME=false"), ) cp.Expect(`"namespace":`) cp.Expect(`"path":`) diff --git a/test/integration/version_int_test.go b/test/integration/version_int_test.go index 5244756011..002d82608b 100644 --- a/test/integration/version_int_test.go +++ b/test/integration/version_int_test.go @@ -21,7 +21,7 @@ func (suite *VersionIntegrationTestSuite) TestNotDev() { defer ts.Close() cp := ts.Spawn("--version") - suite.NotContains(cp.TrimmedSnapshot(), "(dev)") + suite.NotContains(cp.Output(), "(dev)") cp.ExpectExitCode(0) } diff --git a/test/integration/vscode_int_test.go b/test/integration/vscode_int_test.go index 5b270f7b35..137443007d 100644 --- a/test/integration/vscode_int_test.go +++ b/test/integration/vscode_int_test.go @@ -10,6 +10,7 @@ import ( "github.com/ActiveState/cli/internal/fileutils" "github.com/ActiveState/cli/internal/testhelpers/e2e" "github.com/ActiveState/cli/internal/testhelpers/tagsuite" + "github.com/ActiveState/termtest" ) func (suite *PushIntegrationTestSuite) TestInitAndPush_VSCode() { @@ -29,16 +30,16 @@ func (suite *PushIntegrationTestSuite) TestInitAndPush_VSCode() { filepath.Join(ts.Dirs.Work, namespace), ) cp.ExpectExitCode(0) - suite.Contains(cp.TrimmedSnapshot(), "Skipping runtime setup because it was disabled by an environment variable") - suite.Contains(cp.TrimmedSnapshot(), "{") - suite.Contains(cp.TrimmedSnapshot(), "}") + suite.Contains(cp.Output(), "Skipping runtime setup because it was disabled by an environment variable") + suite.Contains(cp.Output(), "{") + suite.Contains(cp.Output(), "}") wd := filepath.Join(cp.WorkDirectory(), namespace) cp = ts.SpawnWithOpts( - e2e.WithArgs("push", "--output", "editor"), - e2e.WithWorkDirectory(wd), + e2e.OptArgs("push", "--output", "editor"), + e2e.OptWD(wd), ) cp.ExpectExitCode(0) - suite.Equal("", cp.TrimmedSnapshot()) + suite.Equal("", strings.TrimSpace(cp.Snapshot())) // check that pushed project exists cp = ts.Spawn("show", namespace) @@ -73,8 +74,9 @@ func (suite *ShowIntegrationTestSuite) TestShow_VSCode() { } var out ShowOutput - err := json.Unmarshal([]byte(cp.TrimmedSnapshot()), &out) - suite.Require().NoError(err, "Failed to parse JSON from: %s", cp.TrimmedSnapshot()) + snapshot := cp.StrippedSnapshot() + err := json.Unmarshal([]byte(snapshot), &out) + suite.Require().NoError(err, "Failed to parse JSON from: %s", snapshot) suite.Equal("Show", out.Name) suite.Equal(e2e.PersistentUsername, out.Organization) suite.Equal("Public", out.Visibility) @@ -111,7 +113,7 @@ func (suite *PushIntegrationTestSuite) TestOrganizations_VSCode() { expected, err := json.Marshal(org) suite.Require().NoError(err) - suite.Contains(cp.TrimmedSnapshot(), string(expected)) + suite.Contains(cp.Output(), string(expected)) } func (suite *AuthIntegrationTestSuite) TestAuth_VSCode() { @@ -131,16 +133,16 @@ func (suite *AuthIntegrationTestSuite) TestAuth_VSCode() { defer ts.Close() cp := ts.SpawnWithOpts( - e2e.WithArgs("auth", "--username", e2e.PersistentUsername, "--password", e2e.PersistentPassword, "--output", "editor"), - e2e.HideCmdLine(), + e2e.OptArgs("auth", "--username", e2e.PersistentUsername, "--password", e2e.PersistentPassword, "--output", "editor"), + e2e.OptHideArgs(), ) cp.Expect(`"privateProjects":false}`) cp.ExpectExitCode(0) - suite.Equal(string(expected), cp.TrimmedSnapshot()) + suite.Equal(string(expected), strings.TrimSpace(cp.Snapshot())) cp = ts.Spawn("export", "jwt", "--output", "editor") cp.ExpectExitCode(0) - suite.Assert().Greater(len(cp.TrimmedSnapshot()), 3, "expected jwt token to be non-empty") + suite.Assert().NotEmpty(strings.TrimSpace(cp.Snapshot()), "expected jwt token to be non-empty") } func (suite *PackageIntegrationTestSuite) TestPackages_VSCode() { @@ -165,8 +167,9 @@ func (suite *PackageIntegrationTestSuite) TestPackages_VSCode() { } var po []PackageOutput - err := json.Unmarshal([]byte(cp.TrimmedSnapshot()), &po) - suite.Require().NoError(err, "Could not parse JSON from: %s", cp.TrimmedSnapshot()) + out := cp.StrippedSnapshot() + err := json.Unmarshal([]byte(out), &po) + suite.Require().NoError(err, "Could not parse JSON from: %s", out) suite.Len(po, 2) } @@ -176,27 +179,30 @@ func (suite *ProjectsIntegrationTestSuite) TestProjects_VSCode() { ts := e2e.New(suite.T(), false) defer ts.Close() - cp := ts.SpawnWithOpts(e2e.WithArgs("checkout", "ActiveState-CLI/small-python")) + cp := ts.SpawnWithOpts(e2e.OptArgs("checkout", "ActiveState-CLI/small-python")) cp.ExpectExitCode(0) - cp = ts.SpawnWithOpts(e2e.WithArgs("checkout", "ActiveState-CLI/Python3")) + cp = ts.SpawnWithOpts(e2e.OptArgs("checkout", "ActiveState-CLI/Python3")) cp.ExpectExitCode(0) // Verify separate "local_checkouts" and "executables" fields for editor output. - cp = ts.SpawnWithOpts(e2e.WithArgs("projects", "--output", "editor")) + cp = ts.SpawnWithOpts( + e2e.OptArgs("projects", "--output", "editor"), + e2e.OptTermTest(termtest.OptCols(2000)), // Line breaks make it hard to assert long output + ) cp.Expect(`"name":"Python3"`) cp.Expect(`"local_checkouts":["`) if runtime.GOOS != "windows" { - cp.ExpectLongString(filepath.Join(ts.Dirs.Work, "Python3") + `"]`) + cp.Expect(filepath.Join(ts.Dirs.Work, "Python3") + `"]`) } else { // Windows uses the long path here. longPath, _ := fileutils.GetLongPathName(filepath.Join(ts.Dirs.Work, "Python3")) - cp.ExpectLongString(strings.ReplaceAll(longPath, "\\", "\\\\") + `"]`) + cp.Expect(strings.ReplaceAll(longPath, "\\", "\\\\") + `"]`) } cp.Expect(`"executables":["`) if runtime.GOOS != "windows" { - cp.ExpectLongString(ts.Dirs.Cache) + cp.Expect(ts.Dirs.Cache) } else { - cp.ExpectLongString(strings.ReplaceAll(ts.Dirs.Cache, "\\", "\\\\")) + cp.Expect(strings.ReplaceAll(ts.Dirs.Cache, "\\", "\\\\")) } cp.ExpectExitCode(0) } diff --git a/vendor/github.com/kr/pty/.gitignore b/vendor/github.com/ActiveState/pty/.gitignore similarity index 100% rename from vendor/github.com/kr/pty/.gitignore rename to vendor/github.com/ActiveState/pty/.gitignore diff --git a/vendor/github.com/ActiveState/pty/Dockerfile.golang b/vendor/github.com/ActiveState/pty/Dockerfile.golang new file mode 100644 index 0000000000..2ee82a3a1f --- /dev/null +++ b/vendor/github.com/ActiveState/pty/Dockerfile.golang @@ -0,0 +1,17 @@ +ARG GOVERSION=1.14 +FROM golang:${GOVERSION} + +# Set base env. +ARG GOOS=linux +ARG GOARCH=amd64 +ENV GOOS=${GOOS} GOARCH=${GOARCH} CGO_ENABLED=0 GOFLAGS='-v -ldflags=-s -ldflags=-w' + +# Pre compile the stdlib for 386/arm (32bits). +RUN go build -a std + +# Add the code to the image. +WORKDIR pty +ADD . . + +# Build the lib. +RUN go build diff --git a/vendor/github.com/ActiveState/pty/Dockerfile.riscv b/vendor/github.com/ActiveState/pty/Dockerfile.riscv new file mode 100644 index 0000000000..7a30c94d03 --- /dev/null +++ b/vendor/github.com/ActiveState/pty/Dockerfile.riscv @@ -0,0 +1,23 @@ +# NOTE: Using 1.13 as a base to build the RISCV compiler, the resulting version is based on go1.6. +FROM golang:1.13 + +# Clone and complie a riscv compatible version of the go compiler. +RUN git clone https://review.gerrithub.io/riscv/riscv-go /riscv-go +# riscvdev branch HEAD as of 2019-06-29. +RUN cd /riscv-go && git checkout 04885fddd096d09d4450726064d06dd107e374bf +ENV PATH=/riscv-go/misc/riscv:/riscv-go/bin:$PATH +RUN cd /riscv-go/src && GOROOT_BOOTSTRAP=$(go env GOROOT) ./make.bash +ENV GOROOT=/riscv-go + +# Set the base env. +ENV GOOS=linux GOARCH=riscv CGO_ENABLED=0 GOFLAGS='-v -ldflags=-s -ldflags=-w' + +# Pre compile the stdlib. +RUN go build -a std + +# Add the code to the image. +WORKDIR pty +ADD . . + +# Build the lib. +RUN go build diff --git a/vendor/github.com/kr/pty/LICENSE b/vendor/github.com/ActiveState/pty/LICENSE similarity index 96% rename from vendor/github.com/kr/pty/LICENSE rename to vendor/github.com/ActiveState/pty/LICENSE index db5a1eda3d..6b7558b6b4 100644 --- a/vendor/github.com/kr/pty/LICENSE +++ b/vendor/github.com/ActiveState/pty/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2019 Keith Rarick +Copyright (c) 2011 Keith Rarick Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated diff --git a/vendor/github.com/ActiveState/pty/README.md b/vendor/github.com/ActiveState/pty/README.md new file mode 100644 index 0000000000..df4bcce0f0 --- /dev/null +++ b/vendor/github.com/ActiveState/pty/README.md @@ -0,0 +1,109 @@ +# pty + +Pty is a Go package for using unix pseudo-terminals and windows ConPty. + +## Install + +```sh +go get github.com/creack/pty +``` + +## Examples + +Note that those examples are for demonstration purpose only, to showcase how to use the library. They are not meant to be used in any kind of production environment. + +__NOTE:__ This package requires `ConPty` support on windows platform, please make sure your windows system meet [these requirements](https://docs.microsoft.com/en-us/windows/console/createpseudoconsole#requirements) + +### Command + +```go +package main + +import ( + "io" + "os" + "os/exec" + + "github.com/creack/pty" +) + +func main() { + c := exec.Command("grep", "--color=auto", "bar") + f, err := pty.Start(c) + if err != nil { + panic(err) + } + + go func() { + f.Write([]byte("foo\n")) + f.Write([]byte("bar\n")) + f.Write([]byte("baz\n")) + f.Write([]byte{4}) // EOT + }() + io.Copy(os.Stdout, f) +} +``` + +### Shell + +```go +package main + +import ( + "io" + "log" + "os" + "os/exec" + "os/signal" + "syscall" + + "github.com/creack/pty" + "golang.org/x/term" +) + +func test() error { + // Create arbitrary command. + c := exec.Command("bash") + + // Start the command with a pty. + ptmx, err := pty.Start(c) + if err != nil { + return err + } + // Make sure to close the pty at the end. + defer func() { _ = ptmx.Close() }() // Best effort. + + // Handle pty size. + ch := make(chan os.Signal, 1) + signal.Notify(ch, syscall.SIGWINCH) + go func() { + for range ch { + if err := pty.InheritSize(os.Stdin, ptmx); err != nil { + log.Printf("error resizing pty: %s", err) + } + } + }() + ch <- syscall.SIGWINCH // Initial resize. + defer func() { signal.Stop(ch); close(ch) }() // Cleanup signals when done. + + // Set stdin in raw mode. + oldState, err := term.MakeRaw(int(os.Stdin.Fd())) + if err != nil { + panic(err) + } + defer func() { _ = term.Restore(int(os.Stdin.Fd()), oldState) }() // Best effort. + + // Copy stdin to the pty and the pty to stdout. + // NOTE: The goroutine will keep reading until the next keystroke before returning. + go func() { _, _ = io.Copy(ptmx, os.Stdin) }() + _, _ = io.Copy(os.Stdout, ptmx) + + return nil +} + +func main() { + if err := test(); err != nil { + log.Fatal(err) + } +} +``` diff --git a/vendor/github.com/ActiveState/pty/asm_solaris_amd64.s b/vendor/github.com/ActiveState/pty/asm_solaris_amd64.s new file mode 100644 index 0000000000..7fbef8ee66 --- /dev/null +++ b/vendor/github.com/ActiveState/pty/asm_solaris_amd64.s @@ -0,0 +1,18 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build gc +//+build gc + +#include "textflag.h" + +// +// System calls for amd64, Solaris are implemented in runtime/syscall_solaris.go +// + +TEXT ·sysvicall6(SB),NOSPLIT,$0-88 + JMP syscall·sysvicall6(SB) + +TEXT ·rawSysvicall6(SB),NOSPLIT,$0-88 + JMP syscall·rawSysvicall6(SB) diff --git a/vendor/github.com/ActiveState/pty/cmd_windows.go b/vendor/github.com/ActiveState/pty/cmd_windows.go new file mode 100644 index 0000000000..d36924f80c --- /dev/null +++ b/vendor/github.com/ActiveState/pty/cmd_windows.go @@ -0,0 +1,356 @@ +//go:build windows +// +build windows + +package pty + +import ( + "bytes" + "errors" + "io" + "os" + "os/exec" + "path/filepath" + "strings" + "syscall" + "unicode/utf16" + "unsafe" + + "golang.org/x/sys/windows" +) + +// copied from os/exec.Cmd for platform compatibility +// we need to use startupInfoEx for pty support, but os/exec.Cmd only have +// support for startupInfo on windows, so we have to rewrite some internal +// logic for windows while keep its behavior compatible with other platforms. + +// windowExecCmd represents an external command being prepared or run. +// +// A cmd cannot be reused after calling its Run, Output or CombinedOutput +// methods. +type windowExecCmd struct { + cmd *exec.Cmd + waitCalled bool + conPty *WindowsPty + attrList *windows.ProcThreadAttributeListContainer +} + +var errProcessNotStarted = errors.New("exec: process has not started yet") + +func (c *windowExecCmd) close() error { + c.attrList.Delete() + _ = c.conPty.Close() + + return nil +} + +func (c *windowExecCmd) Run() error { + err := c.Start() + if err != nil { + return err + } + + return c.Wait() +} + +func (c *windowExecCmd) Wait() error { + if c.cmd.Process == nil { + return errProcessNotStarted + } + + var err error + + if c.waitCalled { + return errors.New("exec: wait was already called") + } + + c.waitCalled = true + c.cmd.ProcessState, err = c.cmd.Process.Wait() + if err != nil { + return err + } + + err = c.close() + if err != nil { + return err + } + + if !c.cmd.ProcessState.Success() { + return &exec.ExitError{ProcessState: c.cmd.ProcessState} + } + + return nil +} + +func (c *windowExecCmd) StdinPipe() (io.WriteCloser, error) { + return nil, ErrUnsupported +} + +func (c *windowExecCmd) StdoutPipe() (io.ReadCloser, error) { + return nil, ErrUnsupported +} + +func (c *windowExecCmd) StderrPipe() (io.ReadCloser, error) { + return nil, ErrUnsupported +} + +func (c *windowExecCmd) Output() ([]byte, error) { + if c.cmd.Stdout != nil { + return nil, errors.New("exec: Stdout already set") + } + + var stdout bytes.Buffer + c.cmd.Stdout = &stdout + + err := c.Run() + return stdout.Bytes(), err +} + +func (c *windowExecCmd) CombinedOutput() ([]byte, error) { + if c.cmd.Stdout != nil { + return nil, errors.New("exec: Stdout already set") + } + if c.cmd.Stderr != nil { + return nil, errors.New("exec: Stderr already set") + } + var b bytes.Buffer + c.cmd.Stdout = &b + c.cmd.Stderr = &b + err := c.Run() + return b.Bytes(), err +} + +func (c *windowExecCmd) argv() []string { + if len(c.cmd.Args) > 0 { + return c.cmd.Args + } + + return []string{c.cmd.Path} +} + +// +// Helpers for working with Windows. These are exact copies of the same utilities found in the go stdlib. +// + +func lookExtensions(path, dir string) (string, error) { + if filepath.Base(path) == path { + path = filepath.Join(".", path) + } + + if dir == "" { + return exec.LookPath(path) + } + + if filepath.VolumeName(path) != "" { + return exec.LookPath(path) + } + + if len(path) > 1 && os.IsPathSeparator(path[0]) { + return exec.LookPath(path) + } + + dirandpath := filepath.Join(dir, path) + + // We assume that LookPath will only add file extension. + lp, err := exec.LookPath(dirandpath) + if err != nil { + return "", err + } + + ext := strings.TrimPrefix(lp, dirandpath) + + return path + ext, nil +} + +func dedupEnvCase(caseInsensitive bool, env []string) []string { + // Construct the output in reverse order, to preserve the + // last occurrence of each key. + out := make([]string, 0, len(env)) + saw := make(map[string]bool, len(env)) + for n := len(env); n > 0; n-- { + kv := env[n-1] + + i := strings.Index(kv, "=") + if i == 0 { + // We observe in practice keys with a single leading "=" on Windows. + // TODO(#49886): Should we consume only the first leading "=" as part + // of the key, or parse through arbitrarily many of them until a non-"="? + i = strings.Index(kv[1:], "=") + 1 + } + if i < 0 { + if kv != "" { + // The entry is not of the form "key=value" (as it is required to be). + // Leave it as-is for now. + // TODO(#52436): should we strip or reject these bogus entries? + out = append(out, kv) + } + continue + } + k := kv[:i] + if caseInsensitive { + k = strings.ToLower(k) + } + if saw[k] { + continue + } + + saw[k] = true + out = append(out, kv) + } + + // Now reverse the slice to restore the original order. + for i := 0; i < len(out)/2; i++ { + j := len(out) - i - 1 + out[i], out[j] = out[j], out[i] + } + + return out +} + +func addCriticalEnv(env []string) []string { + for _, kv := range env { + eq := strings.Index(kv, "=") + if eq < 0 { + continue + } + k := kv[:eq] + if strings.EqualFold(k, "SYSTEMROOT") { + // We already have it. + return env + } + } + + return append(env, "SYSTEMROOT="+os.Getenv("SYSTEMROOT")) +} + +func execEnvDefault(sys *syscall.SysProcAttr) (env []string, err error) { + if sys == nil || sys.Token == 0 { + return syscall.Environ(), nil + } + + var block *uint16 + err = windows.CreateEnvironmentBlock(&block, windows.Token(sys.Token), false) + if err != nil { + return nil, err + } + + defer windows.DestroyEnvironmentBlock(block) + blockp := uintptr(unsafe.Pointer(block)) + + for { + + // find NUL terminator + end := unsafe.Pointer(blockp) + for *(*uint16)(end) != 0 { + end = unsafe.Pointer(uintptr(end) + 2) + } + + n := (uintptr(end) - uintptr(unsafe.Pointer(blockp))) / 2 + if n == 0 { + // environment block ends with empty string + break + } + + entry := (*[(1 << 30) - 1]uint16)(unsafe.Pointer(blockp))[:n:n] + env = append(env, string(utf16.Decode(entry))) + blockp += 2 * (uintptr(len(entry)) + 1) + } + return +} + +func createEnvBlock(envv []string) *uint16 { + if len(envv) == 0 { + return &utf16.Encode([]rune("\x00\x00"))[0] + } + length := 0 + for _, s := range envv { + length += len(s) + 1 + } + length += 1 + + b := make([]byte, length) + i := 0 + for _, s := range envv { + l := len(s) + copy(b[i:i+l], []byte(s)) + copy(b[i+l:i+l+1], []byte{0}) + i = i + l + 1 + } + copy(b[i:i+1], []byte{0}) + + return &utf16.Encode([]rune(string(b)))[0] +} + +func makeCmdLine(args []string) string { + var s string + for _, v := range args { + if s != "" { + s += " " + } + s += windows.EscapeArg(v) + } + return s +} + +func isSlash(c uint8) bool { + return c == '\\' || c == '/' +} + +func normalizeDir(dir string) (name string, err error) { + ndir, err := syscall.FullPath(dir) + if err != nil { + return "", err + } + if len(ndir) > 2 && isSlash(ndir[0]) && isSlash(ndir[1]) { + // dir cannot have \\server\share\path form + return "", syscall.EINVAL + } + return ndir, nil +} + +func volToUpper(ch int) int { + if 'a' <= ch && ch <= 'z' { + ch += 'A' - 'a' + } + return ch +} + +func joinExeDirAndFName(dir, p string) (name string, err error) { + if len(p) == 0 { + return "", syscall.EINVAL + } + if len(p) > 2 && isSlash(p[0]) && isSlash(p[1]) { + // \\server\share\path form + return p, nil + } + if len(p) > 1 && p[1] == ':' { + // has drive letter + if len(p) == 2 { + return "", syscall.EINVAL + } + if isSlash(p[2]) { + return p, nil + } else { + d, err := normalizeDir(dir) + if err != nil { + return "", err + } + if volToUpper(int(p[0])) == volToUpper(int(d[0])) { + return syscall.FullPath(d + "\\" + p[2:]) + } else { + return syscall.FullPath(p) + } + } + } else { + // no drive letter + d, err := normalizeDir(dir) + if err != nil { + return "", err + } + + if isSlash(p[0]) { + return windows.FullPath(d[:2] + p) + } else { + return windows.FullPath(d + "\\" + p) + } + } +} diff --git a/vendor/github.com/ActiveState/pty/doc.go b/vendor/github.com/ActiveState/pty/doc.go new file mode 100644 index 0000000000..033d43add2 --- /dev/null +++ b/vendor/github.com/ActiveState/pty/doc.go @@ -0,0 +1,46 @@ +// Package pty provides functions for working with Unix terminals. +package pty + +import ( + "errors" + "io" +) + +// ErrUnsupported is returned if a function is not +// available on the current platform. +var ErrUnsupported = errors.New("unsupported") + +// Open a pty and its corresponding tty. +func Open() (Pty, Tty, error) { + return open() +} + +type FdHolder interface { + Fd() uintptr +} + +// Pty for terminal control in current process +// for unix systems, the real type is *os.File +// for windows, the real type is a *WindowsPty for ConPTY handle +type Pty interface { + // FdHolder Fd intended to resize Tty of child process in current process + FdHolder + + Name() string + + // WriteString is only used to identify Pty and Tty + WriteString(s string) (n int, err error) + io.ReadWriteCloser +} + +// Tty for data i/o in child process +// for unix systems, the real type is *os.File +// for windows, the real type is a *WindowsTty, which is a combination of two pipe file +type Tty interface { + // FdHolder Fd only intended for manual InheritSize from Pty + FdHolder + + Name() string + + io.ReadWriteCloser +} diff --git a/vendor/github.com/ActiveState/pty/ioctl.go b/vendor/github.com/ActiveState/pty/ioctl.go new file mode 100644 index 0000000000..3cabedd96a --- /dev/null +++ b/vendor/github.com/ActiveState/pty/ioctl.go @@ -0,0 +1,19 @@ +//go:build !windows && !solaris && !aix +// +build !windows,!solaris,!aix + +package pty + +import "syscall" + +const ( + TIOCGWINSZ = syscall.TIOCGWINSZ + TIOCSWINSZ = syscall.TIOCSWINSZ +) + +func ioctl(fd, cmd, ptr uintptr) error { + _, _, e := syscall.Syscall(syscall.SYS_IOCTL, fd, cmd, ptr) + if e != 0 { + return e + } + return nil +} diff --git a/vendor/github.com/ActiveState/pty/ioctl_bsd.go b/vendor/github.com/ActiveState/pty/ioctl_bsd.go new file mode 100644 index 0000000000..db3bf845be --- /dev/null +++ b/vendor/github.com/ActiveState/pty/ioctl_bsd.go @@ -0,0 +1,40 @@ +//go:build darwin || dragonfly || freebsd || netbsd || openbsd +// +build darwin dragonfly freebsd netbsd openbsd + +package pty + +// from +const ( + _IOC_VOID uintptr = 0x20000000 + _IOC_OUT uintptr = 0x40000000 + _IOC_IN uintptr = 0x80000000 + _IOC_IN_OUT uintptr = _IOC_OUT | _IOC_IN + _IOC_DIRMASK = _IOC_VOID | _IOC_OUT | _IOC_IN + + _IOC_PARAM_SHIFT = 13 + _IOC_PARAM_MASK = (1 << _IOC_PARAM_SHIFT) - 1 +) + +func _IOC_PARM_LEN(ioctl uintptr) uintptr { + return (ioctl >> 16) & _IOC_PARAM_MASK +} + +func _IOC(inout uintptr, group byte, ioctl_num uintptr, param_len uintptr) uintptr { + return inout | (param_len&_IOC_PARAM_MASK)<<16 | uintptr(group)<<8 | ioctl_num +} + +func _IO(group byte, ioctl_num uintptr) uintptr { + return _IOC(_IOC_VOID, group, ioctl_num, 0) +} + +func _IOR(group byte, ioctl_num uintptr, param_len uintptr) uintptr { + return _IOC(_IOC_OUT, group, ioctl_num, param_len) +} + +func _IOW(group byte, ioctl_num uintptr, param_len uintptr) uintptr { + return _IOC(_IOC_IN, group, ioctl_num, param_len) +} + +func _IOWR(group byte, ioctl_num uintptr, param_len uintptr) uintptr { + return _IOC(_IOC_IN_OUT, group, ioctl_num, param_len) +} diff --git a/vendor/github.com/ActiveState/pty/ioctl_solaris.go b/vendor/github.com/ActiveState/pty/ioctl_solaris.go new file mode 100644 index 0000000000..bff22dad0b --- /dev/null +++ b/vendor/github.com/ActiveState/pty/ioctl_solaris.go @@ -0,0 +1,48 @@ +//go:build solaris +// +build solaris + +package pty + +import ( + "syscall" + "unsafe" +) + +//go:cgo_import_dynamic libc_ioctl ioctl "libc.so" +//go:linkname procioctl libc_ioctl +var procioctl uintptr + +const ( + // see /usr/include/sys/stropts.h + I_PUSH = uintptr((int32('S')<<8 | 002)) + I_STR = uintptr((int32('S')<<8 | 010)) + I_FIND = uintptr((int32('S')<<8 | 013)) + + // see /usr/include/sys/ptms.h + ISPTM = (int32('P') << 8) | 1 + UNLKPT = (int32('P') << 8) | 2 + PTSSTTY = (int32('P') << 8) | 3 + ZONEPT = (int32('P') << 8) | 4 + OWNERPT = (int32('P') << 8) | 5 + + // see /usr/include/sys/termios.h + TIOCSWINSZ = (uint32('T') << 8) | 103 + TIOCGWINSZ = (uint32('T') << 8) | 104 +) + +type strioctl struct { + icCmd int32 + icTimeout int32 + icLen int32 + icDP unsafe.Pointer +} + +// Defined in asm_solaris_amd64.s. +func sysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) + +func ioctl(fd, cmd, ptr uintptr) error { + if _, _, errno := sysvicall6(uintptr(unsafe.Pointer(&procioctl)), 3, fd, cmd, ptr, 0, 0, 0); errno != 0 { + return errno + } + return nil +} diff --git a/vendor/github.com/ActiveState/pty/ioctl_unsupported.go b/vendor/github.com/ActiveState/pty/ioctl_unsupported.go new file mode 100644 index 0000000000..2449a27ee7 --- /dev/null +++ b/vendor/github.com/ActiveState/pty/ioctl_unsupported.go @@ -0,0 +1,13 @@ +//go:build aix +// +build aix + +package pty + +const ( + TIOCGWINSZ = 0 + TIOCSWINSZ = 0 +) + +func ioctl(fd, cmd, ptr uintptr) error { + return ErrUnsupported +} diff --git a/vendor/github.com/ActiveState/pty/mktypes.bash b/vendor/github.com/ActiveState/pty/mktypes.bash new file mode 100644 index 0000000000..7f71bda6a6 --- /dev/null +++ b/vendor/github.com/ActiveState/pty/mktypes.bash @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +GOOSARCH="${GOOS}_${GOARCH}" +case "$GOOSARCH" in +_* | *_ | _) + echo 'undefined $GOOS_$GOARCH:' "$GOOSARCH" 1>&2 + exit 1 + ;; +esac + +GODEFS="go tool cgo -godefs" + +$GODEFS types.go |gofmt > ztypes_$GOARCH.go + +case $GOOS in +freebsd|dragonfly|netbsd|openbsd) + $GODEFS types_$GOOS.go |gofmt > ztypes_$GOOSARCH.go + ;; +esac diff --git a/vendor/github.com/ActiveState/pty/pty_darwin.go b/vendor/github.com/ActiveState/pty/pty_darwin.go new file mode 100644 index 0000000000..9bdd71d08d --- /dev/null +++ b/vendor/github.com/ActiveState/pty/pty_darwin.go @@ -0,0 +1,68 @@ +//go:build darwin +// +build darwin + +package pty + +import ( + "errors" + "os" + "syscall" + "unsafe" +) + +func open() (pty, tty *os.File, err error) { + pFD, err := syscall.Open("/dev/ptmx", syscall.O_RDWR|syscall.O_CLOEXEC, 0) + if err != nil { + return nil, nil, err + } + p := os.NewFile(uintptr(pFD), "/dev/ptmx") + // In case of error after this point, make sure we close the ptmx fd. + defer func() { + if err != nil { + _ = p.Close() // Best effort. + } + }() + + sname, err := ptsname(p) + if err != nil { + return nil, nil, err + } + + if err := grantpt(p); err != nil { + return nil, nil, err + } + + if err := unlockpt(p); err != nil { + return nil, nil, err + } + + t, err := os.OpenFile(sname, os.O_RDWR|syscall.O_NOCTTY, 0) + if err != nil { + return nil, nil, err + } + return p, t, nil +} + +func ptsname(f *os.File) (string, error) { + n := make([]byte, _IOC_PARM_LEN(syscall.TIOCPTYGNAME)) + + err := ioctl(f.Fd(), syscall.TIOCPTYGNAME, uintptr(unsafe.Pointer(&n[0]))) + if err != nil { + return "", err + } + + for i, c := range n { + if c == 0 { + return string(n[:i]), nil + } + } + return "", errors.New("TIOCPTYGNAME string not NUL-terminated") +} + +func grantpt(f *os.File) error { + return ioctl(f.Fd(), syscall.TIOCPTYGRANT, 0) +} + +func unlockpt(f *os.File) error { + return ioctl(f.Fd(), syscall.TIOCPTYUNLK, 0) +} diff --git a/vendor/github.com/ActiveState/pty/pty_dragonfly.go b/vendor/github.com/ActiveState/pty/pty_dragonfly.go new file mode 100644 index 0000000000..aa916aadf1 --- /dev/null +++ b/vendor/github.com/ActiveState/pty/pty_dragonfly.go @@ -0,0 +1,83 @@ +//go:build dragonfly +// +build dragonfly + +package pty + +import ( + "errors" + "os" + "strings" + "syscall" + "unsafe" +) + +// same code as pty_darwin.go +func open() (pty, tty *os.File, err error) { + p, err := os.OpenFile("/dev/ptmx", os.O_RDWR, 0) + if err != nil { + return nil, nil, err + } + // In case of error after this point, make sure we close the ptmx fd. + defer func() { + if err != nil { + _ = p.Close() // Best effort. + } + }() + + sname, err := ptsname(p) + if err != nil { + return nil, nil, err + } + + if err := grantpt(p); err != nil { + return nil, nil, err + } + + if err := unlockpt(p); err != nil { + return nil, nil, err + } + + t, err := os.OpenFile(sname, os.O_RDWR, 0) + if err != nil { + return nil, nil, err + } + return p, t, nil +} + +func grantpt(f *os.File) error { + _, err := isptmaster(f.Fd()) + return err +} + +func unlockpt(f *os.File) error { + _, err := isptmaster(f.Fd()) + return err +} + +func isptmaster(fd uintptr) (bool, error) { + err := ioctl(fd, syscall.TIOCISPTMASTER, 0) + return err == nil, err +} + +var ( + emptyFiodgnameArg fiodgnameArg + ioctl_FIODNAME = _IOW('f', 120, unsafe.Sizeof(emptyFiodgnameArg)) +) + +func ptsname(f *os.File) (string, error) { + name := make([]byte, _C_SPECNAMELEN) + fa := fiodgnameArg{Name: (*byte)(unsafe.Pointer(&name[0])), Len: _C_SPECNAMELEN, Pad_cgo_0: [4]byte{0, 0, 0, 0}} + + err := ioctl(f.Fd(), ioctl_FIODNAME, uintptr(unsafe.Pointer(&fa))) + if err != nil { + return "", err + } + + for i, c := range name { + if c == 0 { + s := "/dev/" + string(name[:i]) + return strings.Replace(s, "ptm", "pts", -1), nil + } + } + return "", errors.New("TIOCPTYGNAME string not NUL-terminated") +} diff --git a/vendor/github.com/ActiveState/pty/pty_freebsd.go b/vendor/github.com/ActiveState/pty/pty_freebsd.go new file mode 100644 index 0000000000..bcd3b6f90f --- /dev/null +++ b/vendor/github.com/ActiveState/pty/pty_freebsd.go @@ -0,0 +1,81 @@ +//go:build freebsd +// +build freebsd + +package pty + +import ( + "errors" + "os" + "syscall" + "unsafe" +) + +func posixOpenpt(oflag int) (fd int, err error) { + r0, _, e1 := syscall.Syscall(syscall.SYS_POSIX_OPENPT, uintptr(oflag), 0, 0) + fd = int(r0) + if e1 != 0 { + err = e1 + } + return fd, err +} + +func open() (pty, tty *os.File, err error) { + fd, err := posixOpenpt(syscall.O_RDWR | syscall.O_CLOEXEC) + if err != nil { + return nil, nil, err + } + p := os.NewFile(uintptr(fd), "/dev/pts") + // In case of error after this point, make sure we close the pts fd. + defer func() { + if err != nil { + _ = p.Close() // Best effort. + } + }() + + sname, err := ptsname(p) + if err != nil { + return nil, nil, err + } + + t, err := os.OpenFile("/dev/"+sname, os.O_RDWR, 0) + if err != nil { + return nil, nil, err + } + return p, t, nil +} + +func isptmaster(fd uintptr) (bool, error) { + err := ioctl(fd, syscall.TIOCPTMASTER, 0) + return err == nil, err +} + +var ( + emptyFiodgnameArg fiodgnameArg + ioctlFIODGNAME = _IOW('f', 120, unsafe.Sizeof(emptyFiodgnameArg)) +) + +func ptsname(f *os.File) (string, error) { + master, err := isptmaster(f.Fd()) + if err != nil { + return "", err + } + if !master { + return "", syscall.EINVAL + } + + const n = _C_SPECNAMELEN + 1 + var ( + buf = make([]byte, n) + arg = fiodgnameArg{Len: n, Buf: (*byte)(unsafe.Pointer(&buf[0]))} + ) + if err := ioctl(f.Fd(), ioctlFIODGNAME, uintptr(unsafe.Pointer(&arg))); err != nil { + return "", err + } + + for i, c := range buf { + if c == 0 { + return string(buf[:i]), nil + } + } + return "", errors.New("FIODGNAME string not NUL-terminated") +} diff --git a/vendor/github.com/ActiveState/pty/pty_linux.go b/vendor/github.com/ActiveState/pty/pty_linux.go new file mode 100644 index 0000000000..a3b368f561 --- /dev/null +++ b/vendor/github.com/ActiveState/pty/pty_linux.go @@ -0,0 +1,54 @@ +//go:build linux +// +build linux + +package pty + +import ( + "os" + "strconv" + "syscall" + "unsafe" +) + +func open() (pty, tty *os.File, err error) { + p, err := os.OpenFile("/dev/ptmx", os.O_RDWR, 0) + if err != nil { + return nil, nil, err + } + // In case of error after this point, make sure we close the ptmx fd. + defer func() { + if err != nil { + _ = p.Close() // Best effort. + } + }() + + sname, err := ptsname(p) + if err != nil { + return nil, nil, err + } + + if err := unlockpt(p); err != nil { + return nil, nil, err + } + + t, err := os.OpenFile(sname, os.O_RDWR|syscall.O_NOCTTY, 0) //nolint:gosec // Expected Open from a variable. + if err != nil { + return nil, nil, err + } + return p, t, nil +} + +func ptsname(f *os.File) (string, error) { + var n _C_uint + err := ioctl(f.Fd(), syscall.TIOCGPTN, uintptr(unsafe.Pointer(&n))) //nolint:gosec // Expected unsafe pointer for Syscall call. + if err != nil { + return "", err + } + return "/dev/pts/" + strconv.Itoa(int(n)), nil +} + +func unlockpt(f *os.File) error { + var u _C_int + // use TIOCSPTLCK with a pointer to zero to clear the lock + return ioctl(f.Fd(), syscall.TIOCSPTLCK, uintptr(unsafe.Pointer(&u))) //nolint:gosec // Expected unsafe pointer for Syscall call. +} diff --git a/vendor/github.com/ActiveState/pty/pty_netbsd.go b/vendor/github.com/ActiveState/pty/pty_netbsd.go new file mode 100644 index 0000000000..2b20d944c2 --- /dev/null +++ b/vendor/github.com/ActiveState/pty/pty_netbsd.go @@ -0,0 +1,69 @@ +//go:build netbsd +// +build netbsd + +package pty + +import ( + "errors" + "os" + "syscall" + "unsafe" +) + +func open() (pty, tty *os.File, err error) { + p, err := os.OpenFile("/dev/ptmx", os.O_RDWR, 0) + if err != nil { + return nil, nil, err + } + // In case of error after this point, make sure we close the ptmx fd. + defer func() { + if err != nil { + _ = p.Close() // Best effort. + } + }() + + sname, err := ptsname(p) + if err != nil { + return nil, nil, err + } + + if err := grantpt(p); err != nil { + return nil, nil, err + } + + // In NetBSD unlockpt() does nothing, so it isn't called here. + + t, err := os.OpenFile(sname, os.O_RDWR|syscall.O_NOCTTY, 0) + if err != nil { + return nil, nil, err + } + return p, t, nil +} + +func ptsname(f *os.File) (string, error) { + /* + * from ptsname(3): The ptsname() function is equivalent to: + * struct ptmget pm; + * ioctl(fd, TIOCPTSNAME, &pm) == -1 ? NULL : pm.sn; + */ + var ptm ptmget + if err := ioctl(f.Fd(), uintptr(ioctl_TIOCPTSNAME), uintptr(unsafe.Pointer(&ptm))); err != nil { + return "", err + } + name := make([]byte, len(ptm.Sn)) + for i, c := range ptm.Sn { + name[i] = byte(c) + if c == 0 { + return string(name[:i]), nil + } + } + return "", errors.New("TIOCPTSNAME string not NUL-terminated") +} + +func grantpt(f *os.File) error { + /* + * from grantpt(3): Calling grantpt() is equivalent to: + * ioctl(fd, TIOCGRANTPT, 0); + */ + return ioctl(f.Fd(), uintptr(ioctl_TIOCGRANTPT), 0) +} diff --git a/vendor/github.com/ActiveState/pty/pty_openbsd.go b/vendor/github.com/ActiveState/pty/pty_openbsd.go new file mode 100644 index 0000000000..aada5e3f65 --- /dev/null +++ b/vendor/github.com/ActiveState/pty/pty_openbsd.go @@ -0,0 +1,47 @@ +//go:build openbsd +// +build openbsd + +package pty + +import ( + "os" + "syscall" + "unsafe" +) + +func cInt8ToString(in []int8) string { + var s []byte + for _, v := range in { + if v == 0 { + break + } + s = append(s, byte(v)) + } + return string(s) +} + +func open() (pty, tty *os.File, err error) { + /* + * from ptm(4): + * The PTMGET command allocates a free pseudo terminal, changes its + * ownership to the caller, revokes the access privileges for all previous + * users, opens the file descriptors for the pty and tty devices and + * returns them to the caller in struct ptmget. + */ + + p, err := os.OpenFile("/dev/ptm", os.O_RDWR|syscall.O_CLOEXEC, 0) + if err != nil { + return nil, nil, err + } + defer p.Close() + + var ptm ptmget + if err := ioctl(p.Fd(), uintptr(ioctl_PTMGET), uintptr(unsafe.Pointer(&ptm))); err != nil { + return nil, nil, err + } + + pty = os.NewFile(uintptr(ptm.Cfd), cInt8ToString(ptm.Cn[:])) + tty = os.NewFile(uintptr(ptm.Sfd), cInt8ToString(ptm.Sn[:])) + + return pty, tty, nil +} diff --git a/vendor/github.com/ActiveState/pty/pty_solaris.go b/vendor/github.com/ActiveState/pty/pty_solaris.go new file mode 100644 index 0000000000..37f933e600 --- /dev/null +++ b/vendor/github.com/ActiveState/pty/pty_solaris.go @@ -0,0 +1,152 @@ +//go:build solaris +// +build solaris + +package pty + +/* based on: +http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libc/port/gen/pt.c +*/ + +import ( + "errors" + "os" + "strconv" + "syscall" + "unsafe" +) + +func open() (pty, tty *os.File, err error) { + ptmxfd, err := syscall.Open("/dev/ptmx", syscall.O_RDWR|syscall.O_NOCTTY, 0) + if err != nil { + return nil, nil, err + } + p := os.NewFile(uintptr(ptmxfd), "/dev/ptmx") + // In case of error after this point, make sure we close the ptmx fd. + defer func() { + if err != nil { + _ = p.Close() // Best effort. + } + }() + + sname, err := ptsname(p) + if err != nil { + return nil, nil, err + } + + if err := grantpt(p); err != nil { + return nil, nil, err + } + + if err := unlockpt(p); err != nil { + return nil, nil, err + } + + ptsfd, err := syscall.Open(sname, os.O_RDWR|syscall.O_NOCTTY, 0) + if err != nil { + return nil, nil, err + } + t := os.NewFile(uintptr(ptsfd), sname) + + // In case of error after this point, make sure we close the pts fd. + defer func() { + if err != nil { + _ = t.Close() // Best effort. + } + }() + + // pushing terminal driver STREAMS modules as per pts(7) + for _, mod := range []string{"ptem", "ldterm", "ttcompat"} { + if err := streamsPush(t, mod); err != nil { + return nil, nil, err + } + } + + return p, t, nil +} + +func ptsname(f *os.File) (string, error) { + dev, err := ptsdev(f.Fd()) + if err != nil { + return "", err + } + fn := "/dev/pts/" + strconv.FormatInt(int64(dev), 10) + + if err := syscall.Access(fn, 0); err != nil { + return "", err + } + return fn, nil +} + +func unlockpt(f *os.File) error { + istr := strioctl{ + icCmd: UNLKPT, + icTimeout: 0, + icLen: 0, + icDP: nil, + } + return ioctl(f.Fd(), I_STR, uintptr(unsafe.Pointer(&istr))) +} + +func minor(x uint64) uint64 { return x & 0377 } + +func ptsdev(fd uintptr) (uint64, error) { + istr := strioctl{ + icCmd: ISPTM, + icTimeout: 0, + icLen: 0, + icDP: nil, + } + + if err := ioctl(fd, I_STR, uintptr(unsafe.Pointer(&istr))); err != nil { + return 0, err + } + var status syscall.Stat_t + if err := syscall.Fstat(int(fd), &status); err != nil { + return 0, err + } + return uint64(minor(status.Rdev)), nil +} + +type ptOwn struct { + rUID int32 + rGID int32 +} + +func grantpt(f *os.File) error { + if _, err := ptsdev(f.Fd()); err != nil { + return err + } + pto := ptOwn{ + rUID: int32(os.Getuid()), + // XXX should first attempt to get gid of DEFAULT_TTY_GROUP="tty" + rGID: int32(os.Getgid()), + } + istr := strioctl{ + icCmd: OWNERPT, + icTimeout: 0, + icLen: int32(unsafe.Sizeof(strioctl{})), + icDP: unsafe.Pointer(&pto), + } + if err := ioctl(f.Fd(), I_STR, uintptr(unsafe.Pointer(&istr))); err != nil { + return errors.New("access denied") + } + return nil +} + +// streamsPush pushes STREAMS modules if not already done so. +func streamsPush(f *os.File, mod string) error { + buf := []byte(mod) + + // XXX I_FIND is not returning an error when the module + // is already pushed even though truss reports a return + // value of 1. A bug in the Go Solaris syscall interface? + // XXX without this we are at risk of the issue + // https://www.illumos.org/issues/9042 + // but since we are not using libc or XPG4.2, we should not be + // double-pushing modules + + if err := ioctl(f.Fd(), I_FIND, uintptr(unsafe.Pointer(&buf[0]))); err != nil { + return nil + } + return ioctl(f.Fd(), I_PUSH, uintptr(unsafe.Pointer(&buf[0]))) +} diff --git a/vendor/github.com/ActiveState/pty/pty_unsupported.go b/vendor/github.com/ActiveState/pty/pty_unsupported.go new file mode 100644 index 0000000000..c0ef327d39 --- /dev/null +++ b/vendor/github.com/ActiveState/pty/pty_unsupported.go @@ -0,0 +1,12 @@ +//go:build !linux && !darwin && !freebsd && !dragonfly && !netbsd && !openbsd && !solaris && !windows +// +build !linux,!darwin,!freebsd,!dragonfly,!netbsd,!openbsd,!solaris,!windows + +package pty + +import ( + "os" +) + +func open() (pty, tty *os.File, err error) { + return nil, nil, ErrUnsupported +} diff --git a/vendor/github.com/ActiveState/pty/pty_windows.go b/vendor/github.com/ActiveState/pty/pty_windows.go new file mode 100644 index 0000000000..aa8eb0be45 --- /dev/null +++ b/vendor/github.com/ActiveState/pty/pty_windows.go @@ -0,0 +1,187 @@ +//go:build windows +// +build windows + +package pty + +import ( + "fmt" + "os" + "syscall" + "unsafe" + + "golang.org/x/sys/windows" +) + +const ( + PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE = 0x20016 +) + +type WindowsPty struct { + handle windows.Handle + r, w *os.File +} + +type WindowsTty struct { + handle windows.Handle + r, w *os.File +} + +var ( + // NOTE(security): as noted by the comment of syscall.NewLazyDLL and syscall.LoadDLL + // user need to call internal/syscall/windows/sysdll.Add("kernel32.dll") to make sure + // the kernel32.dll is loaded from windows system path + // + // ref: https://pkg.go.dev/syscall@go1.13?GOOS=windows#LoadDLL + kernel32DLL = windows.NewLazyDLL("kernel32.dll") + + // https://docs.microsoft.com/en-us/windows/console/createpseudoconsole + createPseudoConsole = kernel32DLL.NewProc("CreatePseudoConsole") + closePseudoConsole = kernel32DLL.NewProc("ClosePseudoConsole") + + resizePseudoConsole = kernel32DLL.NewProc("ResizePseudoConsole") + getConsoleScreenBufferInfo = kernel32DLL.NewProc("GetConsoleScreenBufferInfo") +) + +func open() (_ Pty, _ Tty, err error) { + pr, consoleW, err := os.Pipe() + if err != nil { + return nil, nil, err + } + + consoleR, pw, err := os.Pipe() + if err != nil { + _ = consoleW.Close() + _ = pr.Close() + return nil, nil, err + } + + var consoleHandle windows.Handle + + err = procCreatePseudoConsole(windows.Handle(consoleR.Fd()), windows.Handle(consoleW.Fd()), + 0, &consoleHandle) + if err != nil { + _ = consoleW.Close() + _ = pr.Close() + _ = pw.Close() + _ = consoleR.Close() + return nil, nil, err + } + + // These pipes can be closed here without any worry + err = consoleW.Close() + if err != nil { + return nil, nil, fmt.Errorf("failed to close pseudo console handle: %w", err) + } + + err = consoleR.Close() + if err != nil { + return nil, nil, fmt.Errorf("failed to close pseudo console handle: %w", err) + } + + return &WindowsPty{ + handle: consoleHandle, + r: pr, + w: pw, + }, &WindowsTty{ + handle: consoleHandle, + r: consoleR, + w: consoleW, + }, nil +} + +func (p *WindowsPty) Name() string { + return p.r.Name() +} + +func (p *WindowsPty) Fd() uintptr { + return uintptr(p.handle) +} + +func (p *WindowsPty) Read(data []byte) (int, error) { + return p.r.Read(data) +} + +func (p *WindowsPty) Write(data []byte) (int, error) { + return p.w.Write(data) +} + +func (p *WindowsPty) WriteString(s string) (int, error) { + return p.w.WriteString(s) +} + +func (p *WindowsPty) UpdateProcThreadAttribute(attrList *windows.ProcThreadAttributeListContainer) error { + var err error + + if err = attrList.Update( + PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE, + unsafe.Pointer(p.handle), + unsafe.Sizeof(p.handle), + ); err != nil { + return fmt.Errorf("failed to update proc thread attributes for pseudo console: %w", err) + } + + return nil +} + +func (p *WindowsPty) Close() error { + _ = p.r.Close() + _ = p.w.Close() + + err := closePseudoConsole.Find() + if err != nil { + return err + } + + _, _, err = closePseudoConsole.Call(uintptr(p.handle)) + return err +} + +func (t *WindowsTty) Name() string { + return t.r.Name() +} + +func (t *WindowsTty) Fd() uintptr { + return uintptr(t.handle) +} + +func (t *WindowsTty) Read(p []byte) (int, error) { + return t.r.Read(p) +} + +func (t *WindowsTty) Write(p []byte) (int, error) { + return t.w.Write(p) +} + +func (t *WindowsTty) Close() error { + _ = t.r.Close() + return t.w.Close() +} + +func procCreatePseudoConsole(hInput windows.Handle, hOutput windows.Handle, dwFlags uint32, consoleHandle *windows.Handle) error { + var r0 uintptr + var err error + + err = createPseudoConsole.Find() + if err != nil { + return err + } + + r0, _, err = createPseudoConsole.Call( + (windowsCoord{X: 80, Y: 30}).Pack(), // size: default 80x30 window + uintptr(hInput), // console input + uintptr(hOutput), // console output + uintptr(dwFlags), // console flags, currently only PSEUDOCONSOLE_INHERIT_CURSOR supported + uintptr(unsafe.Pointer(consoleHandle)), // console handler value return + ) + + if int32(r0) < 0 { + if r0&0x1fff0000 == 0x00070000 { + r0 &= 0xffff + } + + // S_OK: 0 + return syscall.Errno(r0) + } + + return nil +} diff --git a/vendor/github.com/ActiveState/pty/run.go b/vendor/github.com/ActiveState/pty/run.go new file mode 100644 index 0000000000..0b97b94d2f --- /dev/null +++ b/vendor/github.com/ActiveState/pty/run.go @@ -0,0 +1,14 @@ +package pty + +import ( + "os/exec" +) + +// Start assigns a pseudo-terminal tty os.File to c.Stdin, c.Stdout, +// and c.Stderr, calls c.Start, and returns the File of the tty's +// corresponding pty. +// +// Starts the process in a new session and sets the controlling terminal. +func Start(cmd *exec.Cmd) (Pty, error) { + return StartWithSize(cmd, nil) +} diff --git a/vendor/github.com/ActiveState/pty/run_unix.go b/vendor/github.com/ActiveState/pty/run_unix.go new file mode 100644 index 0000000000..6d432919fe --- /dev/null +++ b/vendor/github.com/ActiveState/pty/run_unix.go @@ -0,0 +1,69 @@ +//go:build !windows +// +build !windows + +package pty + +import ( + "os/exec" + "syscall" +) + +// StartWithSize assigns a pseudo-terminal Tty to c.Stdin, c.Stdout, +// and c.Stderr, calls c.Start, and returns the File of the tty's +// corresponding Pty. +// +// This will resize the Pty to the specified size before starting the command. +// Starts the process in a new session and sets the controlling terminal. +func StartWithSize(c *exec.Cmd, sz *Winsize) (Pty, error) { + if c.SysProcAttr == nil { + c.SysProcAttr = &syscall.SysProcAttr{} + } + c.SysProcAttr.Setsid = true + c.SysProcAttr.Setctty = true + return StartWithAttrs(c, sz, c.SysProcAttr) +} + +// StartWithAttrs assigns a pseudo-terminal Tty to c.Stdin, c.Stdout, +// and c.Stderr, calls c.Start, and returns the File of the tty's +// corresponding Pty. +// +// This will resize the Pty to the specified size before starting the command if a size is provided. +// The `attrs` parameter overrides the one set in c.SysProcAttr. +// +// This should generally not be needed. Used in some edge cases where it is needed to create a pty +// without a controlling terminal. +func StartWithAttrs(c *exec.Cmd, sz *Winsize, attrs *syscall.SysProcAttr) (Pty, error) { + pty, tty, err := open() + if err != nil { + return nil, err + } + defer func() { + // always close tty fds since it's being used in another process + // but pty is kept to resize tty + _ = tty.Close() + }() + + if sz != nil { + if err := Setsize(pty, sz); err != nil { + _ = pty.Close() + return nil, err + } + } + if c.Stdout == nil { + c.Stdout = tty + } + if c.Stderr == nil { + c.Stderr = tty + } + if c.Stdin == nil { + c.Stdin = tty + } + + c.SysProcAttr = attrs + + if err := c.Start(); err != nil { + _ = pty.Close() + return nil, err + } + return pty, err +} diff --git a/vendor/github.com/ActiveState/pty/run_windows.go b/vendor/github.com/ActiveState/pty/run_windows.go new file mode 100644 index 0000000000..8b2a511a67 --- /dev/null +++ b/vendor/github.com/ActiveState/pty/run_windows.go @@ -0,0 +1,230 @@ +//go:build windows +// +build windows + +package pty + +import ( + "errors" + "fmt" + "os" + "os/exec" + "syscall" + "unsafe" + + "golang.org/x/sys/windows" +) + +// StartWithSize assigns a pseudo-terminal Tty to c.Stdin, c.Stdout, +// and c.Stderr, calls c.Start, and returns the File of the tty's +// corresponding Pty. +// +// This will resize the Pty to the specified size before starting the command. +// Starts the process in a new session and sets the controlling terminal. +func StartWithSize(c *exec.Cmd, sz *Winsize) (Pty, error) { + return StartWithAttrs(c, sz, c.SysProcAttr) +} + +// StartWithAttrs assigns a pseudo-terminal Tty to c.Stdin, c.Stdout, +// and c.Stderr, calls c.Start, and returns the File of the tty's +// corresponding Pty. +// +// This will resize the Pty to the specified size before starting the command if a size is provided. +// The `attrs` parameter overrides the one set in c.SysProcAttr. +// +// This should generally not be needed. Used in some edge cases where it is needed to create a pty +// without a controlling terminal. +func StartWithAttrs(c *exec.Cmd, sz *Winsize, attrs *syscall.SysProcAttr) (Pty, error) { + pty, _, err := open() + if err != nil { + return nil, err + } + + defer func() { + // unlike unix command exec, do not close tty unless error happened + if err != nil { + _ = pty.Close() + } + }() + + if sz != nil { + if err = Setsize(pty, sz); err != nil { + return nil, err + } + } + + // unlike unix command exec, do not set stdin/stdout/stderr + + c.SysProcAttr = attrs + + // do not use os/exec.Start since we need to append console handler to startup info + + w := windowExecCmd{ + cmd: c, + waitCalled: false, + conPty: pty.(*WindowsPty), + } + + err = w.Start() + if err != nil { + return nil, err + } + + return pty, err +} + +// Start the specified command but does not wait for it to complete. +// +// If Start returns successfully, the c.Process field will be set. +// +// The Wait method will return the exit code and release associated resources +// once the command exits. +func (c *windowExecCmd) Start() error { + if c.cmd.Process != nil { + return errors.New("exec: already started") + } + + var argv0 = c.cmd.Path + var argv0p *uint16 + var argvp *uint16 + var dirp *uint16 + var err error + + sys := c.cmd.SysProcAttr + if sys == nil { + sys = &syscall.SysProcAttr{} + } + + if c.cmd.Env == nil { + c.cmd.Env, err = execEnvDefault(sys) + if err != nil { + return err + } + } + + var lp string + + lp, err = lookExtensions(c.cmd.Path, c.cmd.Dir) + if err != nil { + return err + } + + c.cmd.Path = lp + + if len(c.cmd.Dir) != 0 { + // Windows CreateProcess looks for argv0 relative to the current + // directory, and, only once the new process is started, it does + // Chdir(attr.Dir). We are adjusting for that difference here by + // making argv0 absolute. + + argv0, err = joinExeDirAndFName(c.cmd.Dir, c.cmd.Path) + if err != nil { + return err + } + } + + argv0p, err = syscall.UTF16PtrFromString(argv0) + if err != nil { + return err + } + + var cmdline string + + // Windows CreateProcess takes the command line as a single string: + // use attr.CmdLine if set, else build the command line by escaping + // and joining each argument with spaces + if sys.CmdLine != "" { + cmdline = sys.CmdLine + } else { + cmdline = makeCmdLine(c.argv()) + } + + if len(cmdline) != 0 { + argvp, err = windows.UTF16PtrFromString(cmdline) + if err != nil { + return err + } + } + + if len(c.cmd.Dir) != 0 { + dirp, err = windows.UTF16PtrFromString(c.cmd.Dir) + if err != nil { + return err + } + } + + // Acquire the fork lock so that no other threads + // create new fds that are not yet close-on-exec + // before we fork. + syscall.ForkLock.Lock() + defer syscall.ForkLock.Unlock() + + siEx := new(windows.StartupInfoEx) + siEx.Flags = windows.STARTF_USESTDHANDLES + + if sys.HideWindow { + siEx.Flags |= syscall.STARTF_USESHOWWINDOW + siEx.ShowWindow = syscall.SW_HIDE + } + + pi := new(windows.ProcessInformation) + + // Need EXTENDED_STARTUPINFO_PRESENT as we're making use of the attribute list field. + flags := sys.CreationFlags | uint32(windows.CREATE_UNICODE_ENVIRONMENT) | windows.EXTENDED_STARTUPINFO_PRESENT + + c.attrList, err = windows.NewProcThreadAttributeList(1) + if err != nil { + return fmt.Errorf("failed to initialize process thread attribute list: %w", err) + } + + if c.conPty != nil { + if err = c.conPty.UpdateProcThreadAttribute(c.attrList); err != nil { + return err + } + } + + siEx.ProcThreadAttributeList = c.attrList.List() + siEx.Cb = uint32(unsafe.Sizeof(*siEx)) + + if sys.Token != 0 { + err = windows.CreateProcessAsUser( + windows.Token(sys.Token), + argv0p, + argvp, + nil, + nil, + false, + flags, + createEnvBlock(addCriticalEnv(dedupEnvCase(true, c.cmd.Env))), + dirp, + &siEx.StartupInfo, + pi, + ) + } else { + err = windows.CreateProcess( + argv0p, + argvp, + nil, + nil, + false, + flags, + createEnvBlock(addCriticalEnv(dedupEnvCase(true, c.cmd.Env))), + dirp, + &siEx.StartupInfo, + pi, + ) + } + if err != nil { + return err + } + + defer func() { + _ = windows.CloseHandle(pi.Thread) + }() + + c.cmd.Process, err = os.FindProcess(int(pi.ProcessId)) + if err != nil { + return err + } + + return nil +} diff --git a/vendor/github.com/ActiveState/pty/test_crosscompile.sh b/vendor/github.com/ActiveState/pty/test_crosscompile.sh new file mode 100644 index 0000000000..5bf80f9bb9 --- /dev/null +++ b/vendor/github.com/ActiveState/pty/test_crosscompile.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env sh + +# Test script checking that all expected os/arch compile properly. +# Does not actually test the logic, just the compilation so we make sure we don't break code depending on the lib. + +echo2() { + echo $@ >&2 +} + +trap end 0 +end() { + [ "$?" = 0 ] && echo2 "Pass." || (echo2 "Fail."; exit 1) +} + +cross() { + os=$1 + shift + echo2 "Build for $os." + for arch in $@; do + echo2 " - $os/$arch" + GOOS=$os GOARCH=$arch go build + done + echo2 +} + +set -e + +cross linux amd64 386 arm arm64 ppc64 ppc64le s390x mips mipsle mips64 mips64le +cross darwin amd64 arm64 +cross freebsd amd64 386 arm arm64 +cross netbsd amd64 386 arm arm64 +cross openbsd amd64 386 arm arm64 +cross dragonfly amd64 +cross solaris amd64 +cross windows amd64 386 arm + +# TODO: Fix compilation error on openbsd/arm. +# TODO: Merge the solaris PR. + +# Some os/arch require a different compiler. Run in docker. +if ! hash docker; then + # If docker is not present, stop here. + return +fi + +echo2 "Build for linux." +echo2 " - linux/riscv" +docker build -t creack-pty-test -f Dockerfile.riscv . + +# Golang dropped support for darwin 32bits since go1.15. Make sure the lib still compile with go1.14 on those archs. +echo2 "Build for darwin (32bits)." +echo2 " - darwin/386" +docker build -t creack-pty-test -f Dockerfile.golang --build-arg=GOVERSION=1.14 --build-arg=GOOS=darwin --build-arg=GOARCH=386 . +echo2 " - darwin/arm" +docker build -t creack-pty-test -f Dockerfile.golang --build-arg=GOVERSION=1.14 --build-arg=GOOS=darwin --build-arg=GOARCH=arm . + +# Run a single test for an old go version. Would be best with go1.0, but not available on Dockerhub. +# Using 1.6 as it is the base version for the RISCV compiler. +# Would also be better to run all the tests, not just one, need to refactor this file to allow for specifc archs per version. +echo2 "Build for linux - go1.6." +echo2 " - linux/amd64" +docker build -t creack-pty-test -f Dockerfile.golang --build-arg=GOVERSION=1.6 --build-arg=GOOS=linux --build-arg=GOARCH=amd64 . diff --git a/vendor/github.com/ActiveState/pty/winsize.go b/vendor/github.com/ActiveState/pty/winsize.go new file mode 100644 index 0000000000..7d3d1fc3af --- /dev/null +++ b/vendor/github.com/ActiveState/pty/winsize.go @@ -0,0 +1,31 @@ +package pty + +// Winsize describes the terminal size. +type Winsize struct { + Rows uint16 // ws_row: Number of rows (in cells) + Cols uint16 // ws_col: Number of columns (in cells) + X uint16 // ws_xpixel: Width in pixels + Y uint16 // ws_ypixel: Height in pixels +} + +// InheritSize applies the terminal size of pty to tty. This should be run +// in a signal handler for syscall.SIGWINCH to automatically resize the tty when +// the pty receives a window size change notification. +func InheritSize(pty Pty, tty Tty) error { + size, err := GetsizeFull(pty) + if err != nil { + return err + } + + if err := Setsize(tty, size); err != nil { + return err + } + return nil +} + +// Getsize returns the number of rows (lines) and cols (positions +// in each line) in terminal t. +func Getsize(t FdHolder) (rows, cols int, err error) { + ws, err := GetsizeFull(t) + return int(ws.Rows), int(ws.Cols), err +} diff --git a/vendor/github.com/ActiveState/pty/winsize_unix.go b/vendor/github.com/ActiveState/pty/winsize_unix.go new file mode 100644 index 0000000000..d3e7d15c34 --- /dev/null +++ b/vendor/github.com/ActiveState/pty/winsize_unix.go @@ -0,0 +1,26 @@ +//go:build !windows +// +build !windows + +package pty + +import ( + "syscall" + "unsafe" +) + +// Setsize resizes t to s. +func Setsize(t FdHolder, ws *Winsize) error { + //nolint:gosec // Expected unsafe pointer for Syscall call. + return ioctl(t.Fd(), syscall.TIOCSWINSZ, uintptr(unsafe.Pointer(ws))) +} + +// GetsizeFull returns the full terminal size description. +func GetsizeFull(t FdHolder) (size *Winsize, err error) { + var ws Winsize + + //nolint:gosec // Expected unsafe pointer for Syscall call. + if err := ioctl(t.Fd(), syscall.TIOCGWINSZ, uintptr(unsafe.Pointer(&ws))); err != nil { + return nil, err + } + return &ws, nil +} diff --git a/vendor/github.com/ActiveState/pty/winsize_windows.go b/vendor/github.com/ActiveState/pty/winsize_windows.go new file mode 100644 index 0000000000..5b960046bb --- /dev/null +++ b/vendor/github.com/ActiveState/pty/winsize_windows.go @@ -0,0 +1,89 @@ +//go:build windows +// +build windows + +package pty + +import ( + "syscall" + "unsafe" +) + +// types from golang.org/x/sys/windows +// copy of https://pkg.go.dev/golang.org/x/sys/windows#Coord +type windowsCoord struct { + X int16 + Y int16 +} + +// copy of https://pkg.go.dev/golang.org/x/sys/windows#SmallRect +type windowsSmallRect struct { + Left int16 + Top int16 + Right int16 + Bottom int16 +} + +// copy of https://pkg.go.dev/golang.org/x/sys/windows#ConsoleScreenBufferInfo +type windowsConsoleScreenBufferInfo struct { + Size windowsCoord + CursorPosition windowsCoord + Attributes uint16 + Window windowsSmallRect + MaximumWindowSize windowsCoord +} + +func (c windowsCoord) Pack() uintptr { + return uintptr((int32(c.Y) << 16) | int32(c.X)) +} + +// Setsize resizes t to ws. +func Setsize(t FdHolder, ws *Winsize) error { + var r0 uintptr + var err error + + err = resizePseudoConsole.Find() + if err != nil { + return err + } + + r0, _, err = resizePseudoConsole.Call( + t.Fd(), + (windowsCoord{X: int16(ws.Cols), Y: int16(ws.Rows)}).Pack(), + ) + if int32(r0) < 0 { + if r0&0x1fff0000 == 0x00070000 { + r0 &= 0xffff + } + + // S_OK: 0 + return syscall.Errno(r0) + } + + return nil +} + +// GetsizeFull returns the full terminal size description. +func GetsizeFull(t FdHolder) (size *Winsize, err error) { + err = getConsoleScreenBufferInfo.Find() + if err != nil { + return nil, err + } + + var info windowsConsoleScreenBufferInfo + var r0 uintptr + + r0, _, err = getConsoleScreenBufferInfo.Call(t.Fd(), uintptr(unsafe.Pointer(&info))) + if int32(r0) < 0 { + if r0&0x1fff0000 == 0x00070000 { + r0 &= 0xffff + } + + // S_OK: 0 + return nil, syscall.Errno(r0) + } + + return &Winsize{ + Rows: uint16(info.Window.Bottom - info.Window.Top + 1), + Cols: uint16(info.Window.Right - info.Window.Left + 1), + }, nil +} diff --git a/vendor/github.com/ActiveState/pty/ztypes_386.go b/vendor/github.com/ActiveState/pty/ztypes_386.go new file mode 100644 index 0000000000..d126f4aa58 --- /dev/null +++ b/vendor/github.com/ActiveState/pty/ztypes_386.go @@ -0,0 +1,12 @@ +//go:build 386 +// +build 386 + +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs types.go + +package pty + +type ( + _C_int int32 + _C_uint uint32 +) diff --git a/vendor/github.com/ActiveState/pty/ztypes_amd64.go b/vendor/github.com/ActiveState/pty/ztypes_amd64.go new file mode 100644 index 0000000000..6c4a7677fc --- /dev/null +++ b/vendor/github.com/ActiveState/pty/ztypes_amd64.go @@ -0,0 +1,12 @@ +//go:build amd64 +// +build amd64 + +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs types.go + +package pty + +type ( + _C_int int32 + _C_uint uint32 +) diff --git a/vendor/github.com/ActiveState/pty/ztypes_arm.go b/vendor/github.com/ActiveState/pty/ztypes_arm.go new file mode 100644 index 0000000000..de6fe160ea --- /dev/null +++ b/vendor/github.com/ActiveState/pty/ztypes_arm.go @@ -0,0 +1,12 @@ +//go:build arm +// +build arm + +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs types.go + +package pty + +type ( + _C_int int32 + _C_uint uint32 +) diff --git a/vendor/github.com/ActiveState/pty/ztypes_arm64.go b/vendor/github.com/ActiveState/pty/ztypes_arm64.go new file mode 100644 index 0000000000..c4f315cac1 --- /dev/null +++ b/vendor/github.com/ActiveState/pty/ztypes_arm64.go @@ -0,0 +1,12 @@ +//go:build arm64 +// +build arm64 + +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs types.go + +package pty + +type ( + _C_int int32 + _C_uint uint32 +) diff --git a/vendor/github.com/ActiveState/pty/ztypes_dragonfly_amd64.go b/vendor/github.com/ActiveState/pty/ztypes_dragonfly_amd64.go new file mode 100644 index 0000000000..183c421471 --- /dev/null +++ b/vendor/github.com/ActiveState/pty/ztypes_dragonfly_amd64.go @@ -0,0 +1,17 @@ +//go:build amd64 && dragonfly +// +build amd64,dragonfly + +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs types_dragonfly.go + +package pty + +const ( + _C_SPECNAMELEN = 0x3f +) + +type fiodgnameArg struct { + Name *byte + Len uint32 + Pad_cgo_0 [4]byte +} diff --git a/vendor/github.com/ActiveState/pty/ztypes_freebsd_386.go b/vendor/github.com/ActiveState/pty/ztypes_freebsd_386.go new file mode 100644 index 0000000000..d80dbf7172 --- /dev/null +++ b/vendor/github.com/ActiveState/pty/ztypes_freebsd_386.go @@ -0,0 +1,16 @@ +//go:build 386 && freebsd +// +build 386,freebsd + +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs types_freebsd.go + +package pty + +const ( + _C_SPECNAMELEN = 0x3f +) + +type fiodgnameArg struct { + Len int32 + Buf *byte +} diff --git a/vendor/github.com/ActiveState/pty/ztypes_freebsd_amd64.go b/vendor/github.com/ActiveState/pty/ztypes_freebsd_amd64.go new file mode 100644 index 0000000000..bfab4e4582 --- /dev/null +++ b/vendor/github.com/ActiveState/pty/ztypes_freebsd_amd64.go @@ -0,0 +1,17 @@ +//go:build amd64 && freebsd +// +build amd64,freebsd + +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs types_freebsd.go + +package pty + +const ( + _C_SPECNAMELEN = 0x3f +) + +type fiodgnameArg struct { + Len int32 + Pad_cgo_0 [4]byte + Buf *byte +} diff --git a/vendor/github.com/ActiveState/pty/ztypes_freebsd_arm.go b/vendor/github.com/ActiveState/pty/ztypes_freebsd_arm.go new file mode 100644 index 0000000000..3a8aeae371 --- /dev/null +++ b/vendor/github.com/ActiveState/pty/ztypes_freebsd_arm.go @@ -0,0 +1,16 @@ +//go:build arm && freebsd +// +build arm,freebsd + +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs types_freebsd.go + +package pty + +const ( + _C_SPECNAMELEN = 0x3f +) + +type fiodgnameArg struct { + Len int32 + Buf *byte +} diff --git a/vendor/github.com/ActiveState/pty/ztypes_freebsd_arm64.go b/vendor/github.com/ActiveState/pty/ztypes_freebsd_arm64.go new file mode 100644 index 0000000000..a83924918a --- /dev/null +++ b/vendor/github.com/ActiveState/pty/ztypes_freebsd_arm64.go @@ -0,0 +1,16 @@ +//go:build arm64 && freebsd +// +build arm64,freebsd + +// Code generated by cmd/cgo -godefs; DO NOT EDIT. +// cgo -godefs types_freebsd.go + +package pty + +const ( + _C_SPECNAMELEN = 0xff +) + +type fiodgnameArg struct { + Len int32 + Buf *byte +} diff --git a/vendor/github.com/ActiveState/pty/ztypes_freebsd_ppc64.go b/vendor/github.com/ActiveState/pty/ztypes_freebsd_ppc64.go new file mode 100644 index 0000000000..5fa102fcdf --- /dev/null +++ b/vendor/github.com/ActiveState/pty/ztypes_freebsd_ppc64.go @@ -0,0 +1,14 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs types_freebsd.go + +package pty + +const ( + _C_SPECNAMELEN = 0x3f +) + +type fiodgnameArg struct { + Len int32 + Pad_cgo_0 [4]byte + Buf *byte +} diff --git a/vendor/github.com/ActiveState/pty/ztypes_loong64.go b/vendor/github.com/ActiveState/pty/ztypes_loong64.go new file mode 100644 index 0000000000..3beb5c1762 --- /dev/null +++ b/vendor/github.com/ActiveState/pty/ztypes_loong64.go @@ -0,0 +1,12 @@ +//go:build loong64 +// +build loong64 + +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs types.go + +package pty + +type ( + _C_int int32 + _C_uint uint32 +) diff --git a/vendor/github.com/ActiveState/pty/ztypes_mipsx.go b/vendor/github.com/ActiveState/pty/ztypes_mipsx.go new file mode 100644 index 0000000000..281277977e --- /dev/null +++ b/vendor/github.com/ActiveState/pty/ztypes_mipsx.go @@ -0,0 +1,13 @@ +//go:build (mips || mipsle || mips64 || mips64le) && linux +// +build mips mipsle mips64 mips64le +// +build linux + +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs types.go + +package pty + +type ( + _C_int int32 + _C_uint uint32 +) diff --git a/vendor/github.com/ActiveState/pty/ztypes_netbsd_32bit_int.go b/vendor/github.com/ActiveState/pty/ztypes_netbsd_32bit_int.go new file mode 100644 index 0000000000..2ab7c45598 --- /dev/null +++ b/vendor/github.com/ActiveState/pty/ztypes_netbsd_32bit_int.go @@ -0,0 +1,17 @@ +//go:build (386 || amd64 || arm || arm64) && netbsd +// +build 386 amd64 arm arm64 +// +build netbsd + +package pty + +type ptmget struct { + Cfd int32 + Sfd int32 + Cn [1024]int8 + Sn [1024]int8 +} + +var ( + ioctl_TIOCPTSNAME = 0x48087448 + ioctl_TIOCGRANTPT = 0x20007447 +) diff --git a/vendor/github.com/ActiveState/pty/ztypes_openbsd_32bit_int.go b/vendor/github.com/ActiveState/pty/ztypes_openbsd_32bit_int.go new file mode 100644 index 0000000000..1eb0948167 --- /dev/null +++ b/vendor/github.com/ActiveState/pty/ztypes_openbsd_32bit_int.go @@ -0,0 +1,14 @@ +//go:build (386 || amd64 || arm || arm64 || mips64) && openbsd +// +build 386 amd64 arm arm64 mips64 +// +build openbsd + +package pty + +type ptmget struct { + Cfd int32 + Sfd int32 + Cn [16]int8 + Sn [16]int8 +} + +var ioctl_PTMGET = 0x40287401 diff --git a/vendor/github.com/ActiveState/pty/ztypes_ppc64.go b/vendor/github.com/ActiveState/pty/ztypes_ppc64.go new file mode 100644 index 0000000000..bbb3da8322 --- /dev/null +++ b/vendor/github.com/ActiveState/pty/ztypes_ppc64.go @@ -0,0 +1,12 @@ +//go:build ppc64 +// +build ppc64 + +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs types.go + +package pty + +type ( + _C_int int32 + _C_uint uint32 +) diff --git a/vendor/github.com/ActiveState/pty/ztypes_ppc64le.go b/vendor/github.com/ActiveState/pty/ztypes_ppc64le.go new file mode 100644 index 0000000000..8a4fac3e92 --- /dev/null +++ b/vendor/github.com/ActiveState/pty/ztypes_ppc64le.go @@ -0,0 +1,12 @@ +//go:build ppc64le +// +build ppc64le + +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs types.go + +package pty + +type ( + _C_int int32 + _C_uint uint32 +) diff --git a/vendor/github.com/ActiveState/pty/ztypes_riscvx.go b/vendor/github.com/ActiveState/pty/ztypes_riscvx.go new file mode 100644 index 0000000000..dc5da90506 --- /dev/null +++ b/vendor/github.com/ActiveState/pty/ztypes_riscvx.go @@ -0,0 +1,12 @@ +//go:build riscv || riscv64 +// +build riscv riscv64 + +// Code generated by cmd/cgo -godefs; DO NOT EDIT. +// cgo -godefs types.go + +package pty + +type ( + _C_int int32 + _C_uint uint32 +) diff --git a/vendor/github.com/ActiveState/pty/ztypes_s390x.go b/vendor/github.com/ActiveState/pty/ztypes_s390x.go new file mode 100644 index 0000000000..3433be7ca0 --- /dev/null +++ b/vendor/github.com/ActiveState/pty/ztypes_s390x.go @@ -0,0 +1,12 @@ +//go:build s390x +// +build s390x + +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs types.go + +package pty + +type ( + _C_int int32 + _C_uint uint32 +) diff --git a/vendor/github.com/ActiveState/termtest/.gitignore b/vendor/github.com/ActiveState/termtest/.gitignore index 66fd13c903..bbfd2cb568 100644 --- a/vendor/github.com/ActiveState/termtest/.gitignore +++ b/vendor/github.com/ActiveState/termtest/.gitignore @@ -13,3 +13,5 @@ # Dependency directories (remove the comment below to include it) # vendor/ + +.idea \ No newline at end of file diff --git a/vendor/github.com/ActiveState/termtest/conproc.go b/vendor/github.com/ActiveState/termtest/conproc.go deleted file mode 100644 index 4cfb5d02a3..0000000000 --- a/vendor/github.com/ActiveState/termtest/conproc.go +++ /dev/null @@ -1,431 +0,0 @@ -// Copyright 2020 ActiveState Software. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file - -package termtest - -import ( - "context" - "errors" - "fmt" - "io" - "log" - "os" - "os/exec" - "regexp" - "runtime" - "strings" - "syscall" - "testing" - "time" - - "github.com/ActiveState/termtest/expect" - "github.com/ActiveState/termtest/internal/osutils" -) - -var ( - // ErrNoProcess is returned when a process was expected to be running - ErrNoProcess = errors.New("no command process seems to be running") -) - -type errWaitTimeout struct { - error -} - -func (errWaitTimeout) Timeout() bool { return true } - -// ErrWaitTimeout is returned when we time out waiting for the console process to exit -var ErrWaitTimeout = errWaitTimeout{fmt.Errorf("timeout waiting for exit code")} - -// ConsoleProcess bonds a command with a pseudo-terminal for automation -type ConsoleProcess struct { - opts Options - errs chan error - console *expect.Console - cmd *exec.Cmd - cmdName string - ctx context.Context - cancel func() -} - -// NewTest bonds a command process with a console pty and sets it up for testing -func NewTest(t *testing.T, opts Options) (*ConsoleProcess, error) { - opts.ObserveExpect = TestExpectObserveFn(t) - opts.ObserveSend = TestSendObserveFn(t) - return New(opts) -} - -// New bonds a command process with a console pty. -func New(opts Options) (*ConsoleProcess, error) { - if err := opts.Normalize(); err != nil { - return nil, err - } - - cmd := exec.Command(opts.CmdName, opts.Args...) - cmd.Dir = opts.WorkDirectory - cmd.Env = opts.Environment - - // Create the process in a new process group. - // This makes the behavior more consistent, as it isolates the signal handling from - // the parent processes, which are dependent on the test environment. - cmd.SysProcAttr = osutils.SysProcAttrForNewProcessGroup() - cmdString := osutils.CmdString(cmd) - if opts.HideCmdLine { - cmdString = "*****" - } - fmt.Printf("Spawning '%s' from %s\n", cmdString, opts.WorkDirectory) - - conOpts := []expect.ConsoleOpt{ - expect.WithDefaultTimeout(opts.DefaultTimeout), - expect.WithSendObserver(expect.SendObserver(opts.ObserveSend)), - expect.WithExpectObserver(opts.ObserveExpect), - } - conOpts = append(conOpts, opts.ExtraOpts...) - - console, err := expect.NewConsole(conOpts...) - - if err != nil { - return nil, err - } - - if err = console.Pty.StartProcessInTerminal(cmd); err != nil { - return nil, err - } - - ctx, cancel := context.WithCancel(context.Background()) - - cp := ConsoleProcess{ - opts: opts, - errs: make(chan error), - console: console, - cmd: cmd, - cmdName: opts.CmdName, - ctx: ctx, - cancel: cancel, - } - - // Asynchronously wait for the underlying process to finish and communicate - // results to `cp.errs` channel - // Once the error has been received (by the `wait` function, the TTY is closed) - go func() { - defer close(cp.errs) - - err := cmd.Wait() - - select { - case cp.errs <- err: - case <-cp.ctx.Done(): - log.Println("ConsoleProcess cancelled! You may have forgotten to call ExpectExitCode()") - _ = console.Close() - return - } - - // wait till passthrough-pipe has caught up - cp.console.Pty.WaitTillDrained() - _ = console.Pty.CloseTTY() - }() - - return &cp, nil -} - -// Close cleans up all the resources allocated by the ConsoleProcess -// If the underlying process is still running, it is terminated with a SIGTERM signal. -func (cp *ConsoleProcess) Close() error { - cp.cancel() - - _ = cp.opts.CleanUp() - - if cp.cmd == nil || cp.cmd.Process == nil { - return nil - } - - if cp.cmd.ProcessState != nil && cp.cmd.ProcessState.Exited() { - return nil - } - - if err := cp.cmd.Process.Kill(); err == nil { - return nil - } - - return cp.cmd.Process.Signal(syscall.SIGTERM) -} - -// Executable returns the command name to be executed -func (cp *ConsoleProcess) Executable() string { - return cp.cmdName -} - -// Cmd returns the underlying command -func (cp *ConsoleProcess) Cmd() *exec.Cmd { - return cp.cmd -} - -// WorkDirectory returns the directory in which the command shall be run -func (cp *ConsoleProcess) WorkDirectory() string { - return cp.opts.WorkDirectory -} - -// Snapshot returns a string containing a terminal snap-shot as a user would see it in a "real" terminal -func (cp *ConsoleProcess) Snapshot() string { - return cp.console.Pty.State.String() -} - -// TrimmedSnapshot displays the terminal output a user would see -// however the goroutine that creates this output is separate from this -// function so any output is not synced -func (cp *ConsoleProcess) TrimmedSnapshot() string { - // When the PTY reaches 80 characters it continues output on a new line. - // On Windows this means both a carriage return and a new line. Windows - // also picks up any spaces at the end of the console output, hence all - // the cleaning we must do here. - newlineRe := regexp.MustCompile(`\r?\n`) - return newlineRe.ReplaceAllString(strings.TrimSpace(cp.Snapshot()), "") -} - -// ExpectRe listens to the terminal output and returns once the expected regular expression is matched or -// a timeout occurs -// Default timeout is 10 seconds -func (cp *ConsoleProcess) ExpectRe(value string, timeout ...time.Duration) (string, error) { - opts := []expect.ExpectOpt{expect.RegexpPattern(value)} - if len(timeout) > 0 { - opts = append(opts, expect.WithTimeout(timeout[0])) - } - - return cp.console.Expect(opts...) -} - -// ExpectLongString listens to the terminal output and returns once the expected value is found or -// a timeout occurs -// This function ignores mismatches caused by newline and space characters to account -// for wrappings at the maximum terminal width. -// Default timeout is 10 seconds -func (cp *ConsoleProcess) ExpectLongString(value string, timeout ...time.Duration) (string, error) { - opts := []expect.ExpectOpt{expect.LongString(value)} - if len(timeout) > 0 { - opts = append(opts, expect.WithTimeout(timeout[0])) - } - - return cp.console.Expect(opts...) -} - -// Expect listens to the terminal output and returns once the expected value is found or -// a timeout occurs -// Default timeout is 10 seconds -func (cp *ConsoleProcess) Expect(value string, timeout ...time.Duration) (string, error) { - opts := []expect.ExpectOpt{expect.String(value)} - if len(timeout) > 0 { - opts = append(opts, expect.WithTimeout(timeout[0])) - } - - return cp.console.Expect(opts...) -} - -// ExpectCustom listens to the terminal output and returns once the supplied condition is satisfied or -// a timeout occurs -// Default timeout is 10 seconds -func (cp *ConsoleProcess) ExpectCustom(opt expect.ExpectOpt, timeout ...time.Duration) (string, error) { - opts := []expect.ExpectOpt{opt} - if len(timeout) > 0 { - opts = append(opts, expect.WithTimeout(timeout[0])) - } - - return cp.console.Expect(opts...) -} - -// WaitForInput returns once a shell prompt is active on the terminal -// Default timeout is 10 seconds -func (cp *ConsoleProcess) WaitForInput(timeout ...time.Duration) (string, error) { - homeDir, err := os.UserHomeDir() - if err != nil { - panic(err) - } - - msg := "echo wait_ready_$HOME" - if runtime.GOOS == "windows" { - msg = "echo wait_ready_%USERPROFILE%" - } - - cp.SendLine(msg) - return cp.Expect("wait_ready_"+homeDir, timeout...) -} - -// Send sends a new line to the terminal, as if a user typed it -func (cp *ConsoleProcess) Send(value string) { - _, _ = cp.console.SendLine(value) -} - -// SendLine sends a new line to the terminal, as if a user typed it, the newline sequence is OS aware -func (cp *ConsoleProcess) SendLine(value string) { - _, _ = cp.console.SendOSLine(value) -} - -// SendUnterminated sends a string to the terminal as if a user typed it -func (cp *ConsoleProcess) SendUnterminated(value string) { - _, _ = cp.console.Send(value) -} - -// Signal sends an arbitrary signal to the running process -func (cp *ConsoleProcess) Signal(sig os.Signal) error { - return cp.cmd.Process.Signal(sig) -} - -// SendCtrlC tries to emulate what would happen in an interactive shell, when the user presses Ctrl-C -// Note: On Windows the Ctrl-C event is only reliable caught when the receiving process is -// listening for os.Interrupt signals. -func (cp *ConsoleProcess) SendCtrlC() { - cp.SendUnterminated(string([]byte{0x03})) // 0x03 is ASCII character for ^C -} - -// Stop sends an interrupt signal for the tested process and fails if no process has been started yet. -// Note: This is not supported on Windows -func (cp *ConsoleProcess) Stop() error { - if cp.cmd == nil || cp.cmd.Process == nil { - return ErrNoProcess - } - return cp.cmd.Process.Signal(os.Interrupt) -} - -// MatchState returns the current state of the expect-matcher -func (cp *ConsoleProcess) MatchState() *expect.MatchState { - return cp.console.MatchState -} - -func (cp *ConsoleProcess) rawString() string { - if cp.console.MatchState.Buf == nil { - return "" - } - return cp.console.MatchState.Buf.String() -} - -type exitCodeMatcher struct { - exitCode int - expected bool -} - -func (em *exitCodeMatcher) Match(_ interface{}) bool { - return true -} - -func (em *exitCodeMatcher) Criteria() interface{} { - comparator := "==" - if !em.expected { - comparator = "!=" - } - - return fmt.Sprintf("exit code %s %d", comparator, em.exitCode) -} - -// ExpectExitCode waits for the program under test to terminate, and checks that the returned exit code meets expectations -func (cp *ConsoleProcess) ExpectExitCode(exitCode int, timeout ...time.Duration) (string, error) { - _, err := cp.wait(timeout...) - if err == nil && exitCode == 0 { - return cp.rawString(), nil - } - matchers := []expect.Matcher{&exitCodeMatcher{exitCode, true}} - eexit, ok := err.(*exec.ExitError) - if !ok { - e := fmt.Errorf("process failed with error: %w", err) - cp.opts.ObserveExpect(matchers, cp.MatchState(), e) - return cp.rawString(), e - } - if eexit.ExitCode() != exitCode { - e := fmt.Errorf("exit code wrong: was %d (expected %d)", eexit.ExitCode(), exitCode) - cp.opts.ObserveExpect(matchers, cp.MatchState(), e) - return cp.rawString(), e - } - return cp.rawString(), nil -} - -// ExpectNotExitCode waits for the program under test to terminate, and checks that the returned exit code is not the value provide -func (cp *ConsoleProcess) ExpectNotExitCode(exitCode int, timeout ...time.Duration) (string, error) { - _, err := cp.wait(timeout...) - matchers := []expect.Matcher{&exitCodeMatcher{exitCode, false}} - if err == nil { - if exitCode == 0 { - e := fmt.Errorf("exit code wrong: should not have been 0") - cp.opts.ObserveExpect(matchers, cp.MatchState(), e) - return cp.rawString(), e - } - return cp.rawString(), nil - } - eexit, ok := err.(*exec.ExitError) - if !ok { - e := fmt.Errorf("process failed with error: %w", err) - cp.opts.ObserveExpect(matchers, cp.MatchState(), e) - return cp.rawString(), e - } - if eexit.ExitCode() == exitCode { - e := fmt.Errorf("exit code wrong: should not have been %d", exitCode) - cp.opts.ObserveExpect(matchers, cp.MatchState(), e) - return cp.rawString(), e - } - return cp.rawString(), nil -} - -// Wait waits for the program under test to terminate, not caring about the exit code at all -func (cp *ConsoleProcess) Wait(timeout ...time.Duration) { - _, err := cp.wait(timeout...) - if err != nil { - fmt.Printf("Process exited with error: %v (This is not fatal when using Wait())", err) - } -} - -// forceKill kills the underlying process and waits until it return the exit error -func (cp *ConsoleProcess) forceKill() { - if err := cp.cmd.Process.Kill(); err != nil { - panic(err) - } - <-cp.errs -} - -// wait waits for a console to finish and cleans up all resources -// First it consistently flushes/drains the pipe until the underlying process finishes. -// Note, that without draining the output pipe, the process might hang. -// As soon as the process actually finishes, it waits for the underlying console to be closed -// and gives all readers a chance to read remaining bytes. -func (cp *ConsoleProcess) wait(timeout ...time.Duration) (*os.ProcessState, error) { - if cp.cmd == nil || cp.cmd.Process == nil { - panic(ErrNoProcess.Error()) - } - - t := cp.opts.DefaultTimeout - if len(timeout) > 0 { - t = timeout[0] - } - - finalErrCh := make(chan error) - defer close(finalErrCh) - go func() { - _, err := cp.console.Expect( - expect.Any(expect.PTSClosed, expect.StdinClosed, expect.EOF), - expect.WithTimeout(t), - ) - finalErrCh <- err - }() - - select { - case perr := <-cp.errs: - // wait for the expect call to find EOF in stream - expErr := <-finalErrCh - // close the readers after all bytes from the terminal have been consumed - err := cp.console.CloseReaders() - if err != nil { - log.Printf("Failed to close the console readers: %v", err) - } - // we only expect timeout or EOF errors here, otherwise something went wrong - if expErr != nil && !(os.IsTimeout(expErr) || expErr == io.EOF) { - return nil, fmt.Errorf("unexpected error while waiting for exit code: %v", expErr) - } - return cp.cmd.ProcessState, perr - case <-time.After(t): - // we can ignore the error from the expect (this will also time out) - <-finalErrCh - log.Println("killing process after timeout") - cp.forceKill() - return nil, ErrWaitTimeout - case <-cp.ctx.Done(): - // wait until expect returns (will be forced by closed console) - <-finalErrCh - return nil, fmt.Errorf("ConsoleProcess context canceled") - } -} diff --git a/vendor/github.com/ActiveState/termtest/conpty/LICENSE b/vendor/github.com/ActiveState/termtest/conpty/LICENSE deleted file mode 100644 index 0ea09c8e0d..0000000000 --- a/vendor/github.com/ActiveState/termtest/conpty/LICENSE +++ /dev/null @@ -1,29 +0,0 @@ -BSD 3-Clause License - -Copyright (c) 2020, ActiveState Software -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/ActiveState/termtest/conpty/README.md b/vendor/github.com/ActiveState/termtest/conpty/README.md deleted file mode 100644 index fb093f8559..0000000000 --- a/vendor/github.com/ActiveState/termtest/conpty/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# termtest/conpty - -Support for the [Windows pseudo -console](https://devblogs.microsoft.com/commandline/windows-command-line-introducing-the-windows-pseudo-console-conpty/) -in Go. - -Developed as part of the cross-platform terminal automation library -[expect](https://github.com/ActiveState/termtest/expect) for the [ActiveState -state tool](https://www.activestate.com/products/platform/state-tool/). - -## Example - -See ./cmd/example/main.go - -## Client configuration - -On Windows, you may have to adjust the programme that you are running in the -pseudo-console, by configuring the standard output handler to process virtual -terminal codes. See https://docs.microsoft.com/en-us/windows/console/setconsolemode - -This package comes with a convenience function `InitTerminal()` that you can -use in your client to set this option. - diff --git a/vendor/github.com/ActiveState/termtest/conpty/conpty_windows.go b/vendor/github.com/ActiveState/termtest/conpty/conpty_windows.go deleted file mode 100644 index e0a1821fc9..0000000000 --- a/vendor/github.com/ActiveState/termtest/conpty/conpty_windows.go +++ /dev/null @@ -1,250 +0,0 @@ -// Copyright 2020 ActiveState Software. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file - -package conpty - -import ( - "fmt" - "log" - "os" - "syscall" - "unsafe" - - "golang.org/x/sys/windows" -) - -// ConPty represents a windows pseudo console. -// Attach a process to it by calling the Spawn() method. -// You can send UTF encoded commands to it with Write() and listen to -// its output stream by accessing the output pipe via OutPipe() -type ConPty struct { - hpCon *windows.Handle - pipeFdIn windows.Handle - pipeFdOut windows.Handle - startupInfo startupInfoEx - consoleSize uintptr - inPipe *os.File - outPipe *os.File - attributeListBuffer []byte -} - -// New returns a new ConPty pseudo terminal device -func New(columns int16, rows int16) (c *ConPty, err error) { - c = &ConPty{ - hpCon: new(windows.Handle), - startupInfo: startupInfoEx{}, - consoleSize: uintptr(columns) + (uintptr(rows) << 16), - } - err = c.createPseudoConsoleAndPipes() - if err != nil { - return nil, err - } - err = c.initializeStartupInfoAttachedToPTY() - if err != nil { - return nil, err - } - return -} - -// Close closes the pseudo-terminal and cleans up all attached resources -func (c *ConPty) Close() (err error) { - err = deleteProcThreadAttributeList(c.startupInfo.lpAttributeList) - if err != nil { - log.Printf("Failed to free delete proc thread attribute list: %v", err) - } - /* - _, err = windows.LocalFree(c.startupInfo.lpAttributeList) - if err != nil { - log.Printf("Failed to free the lpAttributeList") - } - */ - err = closePseudoConsole(*c.hpCon) - if err != nil { - log.Printf("Failed to close pseudo console: %v", err) - } - c.inPipe.Close() - c.outPipe.Close() - return -} - -// OutPipe returns the output pipe of the pseudo terminal -func (c *ConPty) OutPipe() *os.File { - return c.outPipe -} - -// InPipe returns input pipe of the pseudo terminal -// Note: It is safer to use the Write method to prevent partially-written VT sequences -// from corrupting the terminal -func (c *ConPty) InPipe() *os.File { - return c.inPipe -} - -func (c *ConPty) OutFd() uintptr { - return c.outPipe.Fd() -} - -// Write safely writes bytes to the pseudo terminal -func (c *ConPty) Write(buf []byte) (uint32, error) { - var n uint32 - err := windows.WriteFile(c.pipeFdIn, buf, &n, nil) - return n, err -} - -var zeroProcAttr syscall.ProcAttr - -// Spawn spawns a new process attached to the pseudo terminal -func (c *ConPty) Spawn(argv0 string, argv []string, attr *syscall.ProcAttr) (pid int, handle uintptr, err error) { - - if attr == nil { - attr = &zeroProcAttr - } - - if attr.Sys != nil { - log.Printf("Warning: SysProc attributes are not supported by Spawn.") - } - - if len(attr.Files) != 0 { - log.Printf("Warning: Ignoring 'Files' attribute in ProcAttr argument.") - } - - if len(attr.Dir) != 0 { - // StartProcess assumes that argv0 is relative to attr.Dir, - // because it implies Chdir(attr.Dir) before executing argv0. - // Windows CreateProcess assumes the opposite: it looks for - // argv0 relative to the current directory, and, only once the new - // process is started, it does Chdir(attr.Dir). We are adjusting - // for that difference here by making argv0 absolute. - var err error - argv0, err = joinExeDirAndFName(attr.Dir, argv0) - if err != nil { - return 0, 0, err - } - } - argv0p, err := windows.UTF16PtrFromString(argv0) - if err != nil { - return 0, 0, err - } - - // Windows CreateProcess takes the command line as a single string: - // use attr.CmdLine if set, else build the command line by escaping - // and joining each argument with spaces - cmdline := makeCmdLine(argv) - - var argvp *uint16 - if len(cmdline) != 0 { - argvp, err = windows.UTF16PtrFromString(cmdline) - if err != nil { - return 0, 0, err - } - } - - var dirp *uint16 - if len(attr.Dir) != 0 { - dirp, err = windows.UTF16PtrFromString(attr.Dir) - if err != nil { - return 0, 0, err - } - } - - c.startupInfo.startupInfo.Flags = windows.STARTF_USESTDHANDLES - - pi := new(windows.ProcessInformation) - - flags := uint32(windows.CREATE_UNICODE_ENVIRONMENT) | extendedStartupinfoPresent - - var zeroSec windows.SecurityAttributes - pSec := &windows.SecurityAttributes{Length: uint32(unsafe.Sizeof(zeroSec)), InheritHandle: 1} - tSec := &windows.SecurityAttributes{Length: uint32(unsafe.Sizeof(zeroSec)), InheritHandle: 1} - - // c.startupInfo.startupInfo.Cb = uint32(unsafe.Sizeof(c.startupInfo)) - err = windows.CreateProcess( - argv0p, - argvp, - pSec, // process handle not inheritable - tSec, // thread handles not inheritable, - false, - flags, - createEnvBlock(addCriticalEnv(dedupEnvCase(true, attr.Env))), - dirp, // use current directory later: dirp, - &c.startupInfo.startupInfo, - pi) - - if err != nil { - return 0, 0, err - } - defer windows.CloseHandle(windows.Handle(pi.Thread)) - - return int(pi.ProcessId), uintptr(pi.Process), nil -} - -func (c *ConPty) createPseudoConsoleAndPipes() (err error) { - var hPipePTYIn windows.Handle - var hPipePTYOut windows.Handle - - if err := windows.CreatePipe(&hPipePTYIn, &c.pipeFdIn, nil, 0); err != nil { - log.Fatalf("Failed to create PTY input pipe: %v", err) - } - if err := windows.CreatePipe(&c.pipeFdOut, &hPipePTYOut, nil, 0); err != nil { - log.Fatalf("Failed to create PTY output pipe: %v", err) - } - - err = createPseudoConsole(c.consoleSize, hPipePTYIn, hPipePTYOut, c.hpCon) - if err != nil { - return fmt.Errorf("failed to create pseudo console: %d, %v", uintptr(*c.hpCon), err) - } - - // Note: We can close the handles to the PTY-end of the pipes here - // because the handles are dup'ed into the ConHost and will be released - // when the ConPTY is destroyed. - if hPipePTYOut != windows.InvalidHandle { - windows.CloseHandle(hPipePTYOut) - } - if hPipePTYIn != windows.InvalidHandle { - windows.CloseHandle(hPipePTYIn) - } - - c.inPipe = os.NewFile(uintptr(c.pipeFdIn), "|0") - c.outPipe = os.NewFile(uintptr(c.pipeFdOut), "|1") - - return -} - -func (c *ConPty) Resize(cols uint16, rows uint16) error { - return resizePseudoConsole(*c.hpCon, uintptr(cols)+(uintptr(rows)<<16)) -} - -func (c *ConPty) initializeStartupInfoAttachedToPTY() (err error) { - - var attrListSize uint64 - c.startupInfo.startupInfo.Cb = uint32(unsafe.Sizeof(c.startupInfo)) - - err = initializeProcThreadAttributeList(0, 1, &attrListSize) - if err != nil { - return fmt.Errorf("could not retrieve list size: %v", err) - } - - c.attributeListBuffer = make([]byte, attrListSize) - // c.startupInfo.lpAttributeList, err = localAlloc(attrListSize) - // if err != nil { - // return fmt.Errorf("Could not allocate local memory: %v", err) - // } - - c.startupInfo.lpAttributeList = windows.Handle(unsafe.Pointer(&c.attributeListBuffer[0])) - - err = initializeProcThreadAttributeList(uintptr(c.startupInfo.lpAttributeList), 1, &attrListSize) - if err != nil { - return fmt.Errorf("failed to initialize proc thread attributes for conpty: %v", err) - } - - err = updateProcThreadAttributeList( - c.startupInfo.lpAttributeList, - procThreadAttributePseudoconsole, - *c.hpCon, - unsafe.Sizeof(*c.hpCon)) - if err != nil { - return fmt.Errorf("failed to update proc thread attributes attributes for conpty usage: %v", err) - } - - return -} diff --git a/vendor/github.com/ActiveState/termtest/conpty/doc.go b/vendor/github.com/ActiveState/termtest/conpty/doc.go deleted file mode 100644 index b423fb62cc..0000000000 --- a/vendor/github.com/ActiveState/termtest/conpty/doc.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2020 ActiveState Software. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file - -// Package conpty provides functions for creating a process attached to a -// ConPTY pseudo-terminal. This allows the process to call console specific -// API functions without an actual terminal being present. -// -// The concept is best explained in this blog post: -// https://devblogs.microsoft.com/commandline/windows-command-line-introducing-the-windows-pseudo-console-conpty/ -package conpty diff --git a/vendor/github.com/ActiveState/termtest/conpty/exec_windows.go b/vendor/github.com/ActiveState/termtest/conpty/exec_windows.go deleted file mode 100644 index 6d0777054d..0000000000 --- a/vendor/github.com/ActiveState/termtest/conpty/exec_windows.go +++ /dev/null @@ -1,161 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. - -// This file has copies of unexported functions form the go source code, -// hence the above copyright message - -package conpty - -import ( - "os" - "strings" - "syscall" - "unicode/utf16" - - "golang.org/x/sys/windows" -) - -// makeCmdLine builds a command line out of args by escaping "special" -// characters and joining the arguments with spaces. -func makeCmdLine(args []string) string { - var s string - for _, v := range args { - if s != "" { - s += " " - } - s += windows.EscapeArg(v) - } - return s -} - -func isSlash(c uint8) bool { - return c == '\\' || c == '/' -} - -func normalizeDir(dir string) (name string, err error) { - ndir, err := syscall.FullPath(dir) - if err != nil { - return "", err - } - if len(ndir) > 2 && isSlash(ndir[0]) && isSlash(ndir[1]) { - // dir cannot have \\server\share\path form - return "", syscall.EINVAL - } - return ndir, nil -} - -func volToUpper(ch int) int { - if 'a' <= ch && ch <= 'z' { - ch += 'A' - 'a' - } - return ch -} - -func joinExeDirAndFName(dir, p string) (name string, err error) { - if len(p) == 0 { - return "", syscall.EINVAL - } - if len(p) > 2 && isSlash(p[0]) && isSlash(p[1]) { - // \\server\share\path form - return p, nil - } - if len(p) > 1 && p[1] == ':' { - // has drive letter - if len(p) == 2 { - return "", syscall.EINVAL - } - if isSlash(p[2]) { - return p, nil - } else { - d, err := normalizeDir(dir) - if err != nil { - return "", err - } - if volToUpper(int(p[0])) == volToUpper(int(d[0])) { - return syscall.FullPath(d + "\\" + p[2:]) - } else { - return syscall.FullPath(p) - } - } - } else { - // no drive letter - d, err := normalizeDir(dir) - if err != nil { - return "", err - } - if isSlash(p[0]) { - return windows.FullPath(d[:2] + p) - } else { - return windows.FullPath(d + "\\" + p) - } - } -} - -// createEnvBlock converts an array of environment strings into -// the representation required by CreateProcess: a sequence of NUL -// terminated strings followed by a nil. -// Last bytes are two UCS-2 NULs, or four NUL bytes. -func createEnvBlock(envv []string) *uint16 { - if len(envv) == 0 { - return &utf16.Encode([]rune("\x00\x00"))[0] - } - length := 0 - for _, s := range envv { - length += len(s) + 1 - } - length += 1 - - b := make([]byte, length) - i := 0 - for _, s := range envv { - l := len(s) - copy(b[i:i+l], []byte(s)) - copy(b[i+l:i+l+1], []byte{0}) - i = i + l + 1 - } - copy(b[i:i+1], []byte{0}) - - return &utf16.Encode([]rune(string(b)))[0] -} - -// dedupEnvCase is dedupEnv with a case option for testing. -// If caseInsensitive is true, the case of keys is ignored. -func dedupEnvCase(caseInsensitive bool, env []string) []string { - out := make([]string, 0, len(env)) - saw := make(map[string]int, len(env)) // key => index into out - for _, kv := range env { - eq := strings.Index(kv, "=") - if eq < 0 { - out = append(out, kv) - continue - } - k := kv[:eq] - if caseInsensitive { - k = strings.ToLower(k) - } - if dupIdx, isDup := saw[k]; isDup { - out[dupIdx] = kv - continue - } - saw[k] = len(out) - out = append(out, kv) - } - return out -} - -// addCriticalEnv adds any critical environment variables that are required -// (or at least almost always required) on the operating system. -// Currently this is only used for Windows. -func addCriticalEnv(env []string) []string { - for _, kv := range env { - eq := strings.Index(kv, "=") - if eq < 0 { - continue - } - k := kv[:eq] - if strings.EqualFold(k, "SYSTEMROOT") { - // We already have it. - return env - } - } - return append(env, "SYSTEMROOT="+os.Getenv("SYSTEMROOT")) -} diff --git a/vendor/github.com/ActiveState/termtest/conpty/syscall_windows.go b/vendor/github.com/ActiveState/termtest/conpty/syscall_windows.go deleted file mode 100644 index 375043114f..0000000000 --- a/vendor/github.com/ActiveState/termtest/conpty/syscall_windows.go +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright 2020 ActiveState Software. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file - -package conpty - -import ( - "unsafe" - - "golang.org/x/sys/windows" -) - -// load some windows system procedures - -var ( - kernel32 = windows.NewLazySystemDLL("kernel32.dll") - procResizePseudoConsole = kernel32.NewProc("ResizePseudoConsole") - procCreatePseudoConsole = kernel32.NewProc("CreatePseudoConsole") - procClosePseudoConsole = kernel32.NewProc("ClosePseudoConsole") - procInitializeProcThreadAttributeList = kernel32.NewProc("InitializeProcThreadAttributeList") - procUpdateProcThreadAttribute = kernel32.NewProc("UpdateProcThreadAttribute") - procLocalAlloc = kernel32.NewProc("LocalAlloc") - procDeleteProcThreadAttributeList = kernel32.NewProc("DeleteProcThreadAttributeList") - procCreateProcessW = kernel32.NewProc("CreateProcessW") -) - -// an extended version of a process startup info, the attribute list points -// to a pseudo terminal object -type startupInfoEx struct { - startupInfo windows.StartupInfo - lpAttributeList windows.Handle -} - -// constant used in CreateProcessW indicating that extended startup info is present -const extendedStartupinfoPresent uint32 = 0x00080000 - -type procThreadAttribute uintptr - -// windows constant needed during initialization of extended startupinfo -const procThreadAttributePseudoconsole procThreadAttribute = 22 | 0x00020000 // this is the only one we support right now - -func initializeProcThreadAttributeList(attributeList uintptr, attributeCount uint32, listSize *uint64) (err error) { - - if attributeList == 0 { - procInitializeProcThreadAttributeList.Call(0, uintptr(attributeCount), 0, uintptr(unsafe.Pointer(listSize))) - return - } - r1, _, e1 := procInitializeProcThreadAttributeList.Call(attributeList, uintptr(attributeCount), 0, uintptr(unsafe.Pointer(listSize))) - - if r1 == 0 { // boolean FALSE - err = e1 - } - - return -} - -func updateProcThreadAttributeList(attributeList windows.Handle, attribute procThreadAttribute, lpValue windows.Handle, lpSize uintptr) (err error) { - - r1, _, e1 := procUpdateProcThreadAttribute.Call(uintptr(attributeList), 0, uintptr(attribute), uintptr(lpValue), lpSize, 0, 0) - - if r1 == 0 { // boolean FALSE - err = e1 - } - - return -} -func deleteProcThreadAttributeList(handle windows.Handle) (err error) { - r1, _, e1 := procDeleteProcThreadAttributeList.Call(uintptr(handle)) - - if r1 == 0 { // boolean FALSE - err = e1 - } - - return -} - -func localAlloc(size uint64) (ptr windows.Handle, err error) { - r1, _, e1 := procLocalAlloc.Call(uintptr(0x0040), uintptr(size)) - if r1 == 0 { - err = e1 - ptr = windows.InvalidHandle - return - } - ptr = windows.Handle(r1) - return -} - -func createPseudoConsole(consoleSize uintptr, ptyIn windows.Handle, ptyOut windows.Handle, hpCon *windows.Handle) (err error) { - r1, _, e1 := procCreatePseudoConsole.Call(consoleSize, uintptr(ptyIn), uintptr(ptyOut), 0, uintptr(unsafe.Pointer(hpCon))) - - if r1 != 0 { // !S_OK - err = e1 - } - return -} - -func resizePseudoConsole(handle windows.Handle, consoleSize uintptr) (err error) { - r1, _, e1 := procResizePseudoConsole.Call(uintptr(handle), consoleSize) - if r1 != 0 { // !S_OK - err = e1 - } - return -} - -func closePseudoConsole(handle windows.Handle) (err error) { - r1, _, e1 := procClosePseudoConsole.Call(uintptr(handle)) - if r1 == 0 { - err = e1 - } - - return -} diff --git a/vendor/github.com/ActiveState/termtest/conpty/term_other.go b/vendor/github.com/ActiveState/termtest/conpty/term_other.go deleted file mode 100644 index daef1c0792..0000000000 --- a/vendor/github.com/ActiveState/termtest/conpty/term_other.go +++ /dev/null @@ -1,7 +0,0 @@ -// +build !windows - -package conpty - -func InitTerminal(_ bool) (func(), error) { - return func() {}, nil -} diff --git a/vendor/github.com/ActiveState/termtest/conpty/term_windows.go b/vendor/github.com/ActiveState/termtest/conpty/term_windows.go deleted file mode 100644 index df091b5bb6..0000000000 --- a/vendor/github.com/ActiveState/termtest/conpty/term_windows.go +++ /dev/null @@ -1,61 +0,0 @@ -// +build windows - -package conpty - -import ( - "fmt" - "log" - "syscall" - - "github.com/Azure/go-ansiterm/winterm" -) - -func InitTerminal(disableNewlineAutoReturn bool) (func(), error) { - stdoutFd := int(syscall.Stdout) - - // fmt.Printf("file descriptors <%d >%d\n", stdinFd, stdoutFd) - - oldOutMode, err := winterm.GetConsoleMode(uintptr(stdoutFd)) - if err != nil { - return func() {}, fmt.Errorf("failed to retrieve stdout mode: %w", err) - } - - // fmt.Printf("old modes: <%d >%d\n", oldInMode, oldOutMode) - newOutMode := oldOutMode | winterm.ENABLE_VIRTUAL_TERMINAL_PROCESSING - if disableNewlineAutoReturn { - newOutMode |= winterm.DISABLE_NEWLINE_AUTO_RETURN - } - - err = winterm.SetConsoleMode(uintptr(stdoutFd), newOutMode) - if err != nil { - return func() {}, fmt.Errorf("failed to set stdout mode: %w", err) - } - - // dump(uintptr(stdoutFd)) - return func() { - err = winterm.SetConsoleMode(uintptr(stdoutFd), oldOutMode) - if err != nil { - log.Fatalf("Failed to reset output terminal mode to %d: %v\n", oldOutMode, err) - } - }, nil -} - -func dump(fd uintptr) { - fmt.Printf("FD=%d\n", fd) - modes, err := winterm.GetConsoleMode(fd) - if err != nil { - panic(err) - } - - fmt.Printf("ENABLE_ECHO_INPUT=%d, ENABLE_PROCESSED_INPUT=%d ENABLE_LINE_INPUT=%d\n", - modes&winterm.ENABLE_ECHO_INPUT, - modes&winterm.ENABLE_PROCESSED_INPUT, - modes&winterm.ENABLE_LINE_INPUT) - fmt.Printf("ENABLE_WINDOW_INPUT=%d, ENABLE_MOUSE_INPUT=%d\n", - modes&winterm.ENABLE_WINDOW_INPUT, - modes&winterm.ENABLE_MOUSE_INPUT) - fmt.Printf("enableVirtualTerminalInput=%d, enableVirtualTerminalProcessing=%d, disableNewlineAutoReturn=%d\n", - modes&winterm.ENABLE_VIRTUAL_TERMINAL_INPUT, - modes&winterm.ENABLE_VIRTUAL_TERMINAL_PROCESSING, - modes&winterm.DISABLE_NEWLINE_AUTO_RETURN) -} diff --git a/vendor/github.com/ActiveState/termtest/expect.go b/vendor/github.com/ActiveState/termtest/expect.go new file mode 100644 index 0000000000..d340777a80 --- /dev/null +++ b/vendor/github.com/ActiveState/termtest/expect.go @@ -0,0 +1,209 @@ +package termtest + +import ( + "fmt" + "regexp" + "strings" + "time" +) + +type ExpectOpts struct { + ExpectTimeout bool + Timeout time.Duration + ErrorHandler ErrorHandler + ErrorMessage string +} + +func NewExpectOpts(opts ...SetExpectOpt) (*ExpectOpts, error) { + o := &ExpectOpts{} + for _, opt := range opts { + if err := opt(o); err != nil { + return nil, err + } + } + return o, nil +} + +func (o *ExpectOpts) ToConsumerOpts() []SetConsOpt { + var consOpts []SetConsOpt + if o.Timeout > 0 { + consOpts = append(consOpts, OptsConsTimeout(o.Timeout)) + } + + return consOpts +} + +type SetExpectOpt func(o *ExpectOpts) error + +func OptExpectErrorMessage(msg string) SetExpectOpt { + return func(o *ExpectOpts) error { + o.ErrorMessage = msg + return nil + } +} + +func OptExpectTimeout(timeout time.Duration) SetExpectOpt { + return func(o *ExpectOpts) error { + o.Timeout = timeout + return nil + } +} + +func OptExpectErrorHandler(handler ErrorHandler) SetExpectOpt { + return func(o *ExpectOpts) error { + o.ErrorHandler = handler + return nil + } +} + +func OptExpectSilenceErrorHandler() SetExpectOpt { + return func(o *ExpectOpts) error { + o.ErrorHandler = SilenceErrorHandler() + return nil + } +} + +func (tt *TermTest) ExpectErrorHandler(rerr *error, opts *ExpectOpts) error { + err := *rerr + if err == nil { + return nil + } + + errorHandler := tt.opts.ExpectErrorHandler + if opts.ErrorHandler != nil { + errorHandler = opts.ErrorHandler + } + + *rerr = errorHandler(tt, err) + return *rerr +} + +func (tt *TermTest) ExpectCustom(consumer consumer, opts ...SetExpectOpt) (rerr error) { + opts = append([]SetExpectOpt{OptExpectTimeout(tt.opts.DefaultTimeout)}, opts...) + expectOpts, err := NewExpectOpts(opts...) + defer tt.ExpectErrorHandler(&rerr, expectOpts) + if err != nil { + return fmt.Errorf("could not create expect options: %w", err) + } + + cons, err := tt.outputProducer.addConsumer(consumer, expectOpts.ToConsumerOpts()...) + if err != nil { + return fmt.Errorf("could not add consumer: %w", err) + } + err = cons.wait() + if err != nil && expectOpts.ErrorMessage != "" { + return fmt.Errorf("%s: %w", expectOpts.ErrorMessage, err) + } + return err +} + +// Expect listens to the terminal output and returns once the expected value is found or a timeout occurs +func (tt *TermTest) Expect(value string, opts ...SetExpectOpt) error { + tt.opts.Logger.Printf("Expect: %#v\n", value) + + return tt.ExpectCustom(func(buffer string) (int, error) { + return tt.expect(value, buffer) + }, append([]SetExpectOpt{OptExpectErrorMessage(fmt.Sprintf("Expected: %#v", value))}, opts...)...) +} + +func (tt *TermTest) expect(value, buffer string) (endPos int, rerr error) { + if tt.opts.NormalizedLineEnds { + tt.opts.Logger.Println("NormalizedLineEnds prior to expect") + value = NormalizeLineEnds(value) + } + + tt.opts.Logger.Printf("expect: '%#v', buffer: '%#v'\n", string(value), strings.Trim(strings.TrimSpace(buffer), "\x00")) + defer func() { + tt.opts.Logger.Printf("Match: %v\n", endPos > 0) + }() + idx := strings.Index(buffer, value) + if idx == -1 { + return 0, nil + } + return idx + len(value), nil +} + +// ExpectRe listens to the terminal output and returns once the expected regular expression is matched or a timeout occurs +// Default timeout is 10 seconds +func (tt *TermTest) ExpectRe(rx *regexp.Regexp, opts ...SetExpectOpt) error { + tt.opts.Logger.Printf("ExpectRe: %s\n", rx.String()) + + return tt.ExpectCustom(func(buffer string) (int, error) { + return expectRe(rx, buffer) + }, append([]SetExpectOpt{OptExpectErrorMessage(fmt.Sprintf("Expected Regex: %#v", rx.String()))}, opts...)...) +} + +func expectRe(rx *regexp.Regexp, buffer string) (int, error) { + idx := rx.FindIndex([]byte(buffer)) + if idx == nil { + return 0, nil + } + return idx[1], nil +} + +// ExpectExitCode waits for the program under test to terminate, and checks that the returned exit code meets expectations +func (tt *TermTest) ExpectExitCode(exitCode int, opts ...SetExpectOpt) error { + return tt.expectExitCode(exitCode, true, opts...) +} + +// ExpectNotExitCode waits for the program under test to terminate, and checks that the returned exit code is not the value provide +func (tt *TermTest) ExpectNotExitCode(exitCode int, opts ...SetExpectOpt) error { + return tt.expectExitCode(exitCode, false, opts...) +} + +// ExpectExit waits for the program under test to terminate, not caring about the exit code +func (tt *TermTest) ExpectExit(opts ...SetExpectOpt) error { + return tt.expectExitCode(-999, false, opts...) +} + +func (tt *TermTest) expectExitCode(exitCode int, match bool, opts ...SetExpectOpt) (rerr error) { + tt.opts.Logger.Printf("Expecting exit code %d: %v", exitCode, match) + defer func() { + tt.opts.Logger.Printf("Expect exit code result: %s", unwrapErrorMessage(rerr)) + }() + + expectOpts, err := NewExpectOpts(opts...) + defer tt.ExpectErrorHandler(&rerr, expectOpts) + if err != nil { + return fmt.Errorf("could not create expect options: %w", err) + } + + timeoutV := tt.opts.DefaultTimeout + if expectOpts.Timeout > 0 { + timeoutV = expectOpts.Timeout + } + + timeoutTotal := time.Now().Add(timeoutV) + + // While Wait() below will wait for the cmd exit, we want to call it here separately because to us cmd.Wait() can + // return an error and still be valid, whereas Wait() would interrupt if it reached that point. + select { + case <-time.After(timeoutV): + return fmt.Errorf("after %s: %w", timeoutV, TimeoutError) + case err := <-waitChan(tt.cmd.Wait): + if err != nil && (tt.cmd.ProcessState == nil || tt.cmd.ProcessState.ExitCode() == 0) { + return fmt.Errorf("cmd wait failed: %w", err) + } + if err := tt.assertExitCode(tt.cmd.ProcessState.ExitCode(), exitCode, match); err != nil { + return err + } + } + + if err := tt.Wait(timeoutTotal.Sub(time.Now())); err != nil { + return fmt.Errorf("wait failed: %w", err) + } + + return nil +} + +func (tt *TermTest) assertExitCode(exitCode, comparable int, match bool) error { + tt.opts.Logger.Printf("assertExitCode: exitCode=%d, comparable=%d, match=%v\n", exitCode, comparable, match) + if compared := exitCode == comparable; compared != match { + if match { + return fmt.Errorf("expected exit code %d, got %d", comparable, exitCode) + } else { + return fmt.Errorf("expected exit code to not be %d", exitCode) + } + } + return nil +} diff --git a/vendor/github.com/ActiveState/termtest/expect/LICENSE b/vendor/github.com/ActiveState/termtest/expect/LICENSE deleted file mode 100644 index af349b6ded..0000000000 --- a/vendor/github.com/ActiveState/termtest/expect/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2018 Netflix, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/ActiveState/termtest/expect/README.md b/vendor/github.com/ActiveState/termtest/expect/README.md deleted file mode 100644 index 70a51eb2a9..0000000000 --- a/vendor/github.com/ActiveState/termtest/expect/README.md +++ /dev/null @@ -1,102 +0,0 @@ -# go-expect - -Package expect provides an expect-like interface to automate control of applications. It is unlike expect in that it does not spawn or manage process lifecycle. This package only focuses on expecting output and sending input through it's pseudoterminal. - -This is a fork of the original repository [Netflix/go-expect](https://github.com/Netflix/go-expect) mostly to add Windows support. This fork has been added to test the [ActiveState state tool](https://www.activestate.com/products/platform/state-tool/) - -Relevant additions: - -- Windows support (Windows 10 and Windows Sever 2019 only) -- `expect.Console` is created with [xpty](https://github.com/ActiveState/termtest/xpty) allowing testing of applications that want to talk to an `xterm`-compatible terminal -- Filter out VT control characters in output. This is important for Windows support, as the windows pseudo-console creates lots of control-characters that can break up words. - -See also [ActiveState/termtest](https://github.com/ActiveState/termtest) for a library that uses this package, but adds more life-cycle management. - -## Usage - -### `os.Exec` example - -```go -package main - -import ( - "log" - "os" - "os/exec" - "time" - - "github.com/ActiveState/termtest/expect" -) - -func main() { - c, err := expect.NewConsole(expect.WithStdout(os.Stdout)) - if err != nil { - log.Fatal(err) - } - defer c.Close() - - cmd := exec.Command("vi") - cmd.Stdin = c.Tty() - cmd.Stdout = c.Tty() - cmd.Stderr = c.Tty() - - go func() { - c.ExpectEOF() - }() - - err = cmd.Start() - if err != nil { - log.Fatal(err) - } - - time.Sleep(time.Second) - c.Send("iHello world\x1b") - time.Sleep(time.Second) - c.Send("dd") - time.Sleep(time.Second) - c.SendLine(":q!") - - err = cmd.Wait() - if err != nil { - log.Fatal(err) - } -} -``` - -### `golang.org/x/crypto/ssh/terminal` example - -``` -package main - -import ( - "fmt" - - "golang.org/x/crypto/ssh/terminal" - - "github.com/ActiveState/termtest/expect" -) - -func getPassword(fd int) string { - bytePassword, _ := terminal.ReadPassword(fd) - - return string(bytePassword) -} - -func main() { - c, _ := expect.NewConsole() - - defer c.Close() - - donec := make(chan struct{}) - go func() { - defer close(donec) - c.SendLine("hunter2") - }() - - echoText := getPassword(int(c.Tty().Fd())) - - <-donec - - fmt.Printf("\nPassword from stdin: %s", echoText) -} -``` diff --git a/vendor/github.com/ActiveState/termtest/expect/console.go b/vendor/github.com/ActiveState/termtest/expect/console.go deleted file mode 100644 index 104f66d34a..0000000000 --- a/vendor/github.com/ActiveState/termtest/expect/console.go +++ /dev/null @@ -1,309 +0,0 @@ -// Copyright 2018 Netflix, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package expect - -import ( - "bytes" - "fmt" - "io" - "io/ioutil" - "log" - "os" - "runtime" - "time" - - "github.com/ActiveState/termtest/expect/internal/osutils" - "github.com/ActiveState/termtest/xpty" - "github.com/ActiveState/vt10x" -) - -// Console is an interface to automate input and output for interactive -// applications. Console can block until a specified output is received and send -// input back on it's tty. Console can also multiplex other sources of input -// and multiplex its output to other writers. -type Console struct { - opts ConsoleOpts - Pty *xpty.Xpty - MatchState *MatchState - closers []io.Closer -} - -type coord struct { - x int - y int -} - -// MatchState describes the state of the terminal while trying to match it against an expectation -type MatchState struct { - // TermState is the current terminal state - TermState *vt10x.State - // Buf is a buffer of the raw characters parsed since the last match - Buf *bytes.Buffer - prevCoords []coord -} - -// UnwrappedStringToCursorFromMatch returns the parsed string from the position of the n-last match to the cursor position -// Terminal EOL-wrapping is removed -func (ms *MatchState) UnwrappedStringToCursorFromMatch(n int) string { - var c coord - numCoords := len(ms.prevCoords) - if numCoords > 0 { - if n < numCoords { - c = ms.prevCoords[numCoords-1-n] - } - } - return ms.TermState.UnwrappedStringToCursorFrom(c.y, c.x) -} - -func (ms *MatchState) markMatch() { - c := coord{} - c.x, c.y = ms.TermState.GlobalCursor() - ms.prevCoords = append(ms.prevCoords, c) -} - -// ConsoleOpt allows setting Console options. -type ConsoleOpt func(*ConsoleOpts) error - -// ConsoleOpts provides additional options on creating a Console. -type ConsoleOpts struct { - Logger *log.Logger - Stdins []io.Reader - Stdouts []io.Writer - Closers []io.Closer - ExpectObservers []ExpectObserver - SendObservers []SendObserver - ReadTimeout *time.Duration - TermCols int - TermRows int -} - -// ExpectObserver provides an interface for a function callback that will -// be called after each Expect operation. -// matchers will be the list of active matchers when an error occurred, -// or a list of matchers that matched `buf` when err is nil. -// buf is the captured output that was matched against. -// err is error that might have occurred. May be nil. -type ExpectObserver func(matchers []Matcher, ms *MatchState, err error) - -// SendObserver provides an interface for a function callback that will -// be called after each Send operation. -// msg is the string that was sent. -// num is the number of bytes actually sent. -// err is the error that might have occurred. May be nil. -type SendObserver func(msg string, num int, err error) - -// WithStdout adds writers that Console duplicates writes to, similar to the -// Unix tee(1) command. -// -// Each write is written to each listed writer, one at a time. Console is the -// last writer, writing to it's internal buffer for matching expects. -// If a listed writer returns an error, that overall write operation stops and -// returns the error; it does not continue down the list. -func WithStdout(writers ...io.Writer) ConsoleOpt { - return func(opts *ConsoleOpts) error { - opts.Stdouts = append(opts.Stdouts, writers...) - return nil - } -} - -// WithStdin adds readers that bytes read are written to Console's tty. If a -// listed reader returns an error, that reader will not be continued to read. -func WithStdin(readers ...io.Reader) ConsoleOpt { - return func(opts *ConsoleOpts) error { - opts.Stdins = append(opts.Stdins, readers...) - return nil - } -} - -// WithCloser adds closers that are closed in order when Console is closed. -func WithCloser(closer ...io.Closer) ConsoleOpt { - return func(opts *ConsoleOpts) error { - opts.Closers = append(opts.Closers, closer...) - return nil - } -} - -// WithLogger adds a logger for Console to log debugging information to. By -// default Console will discard logs. -func WithLogger(logger *log.Logger) ConsoleOpt { - return func(opts *ConsoleOpts) error { - opts.Logger = logger - return nil - } -} - -// WithExpectObserver adds an ExpectObserver to allow monitoring Expect operations. -func WithExpectObserver(observers ...ExpectObserver) ConsoleOpt { - return func(opts *ConsoleOpts) error { - opts.ExpectObservers = append(opts.ExpectObservers, observers...) - return nil - } -} - -// WithSendObserver adds a SendObserver to allow monitoring Send operations. -func WithSendObserver(observers ...SendObserver) ConsoleOpt { - return func(opts *ConsoleOpts) error { - opts.SendObservers = append(opts.SendObservers, observers...) - return nil - } -} - -// WithDefaultTimeout sets a default read timeout during Expect statements. -func WithDefaultTimeout(timeout time.Duration) ConsoleOpt { - return func(opts *ConsoleOpts) error { - opts.ReadTimeout = &timeout - return nil - } -} - -// WithTermCols sets the number of columns in the terminal (Default: 80) -func WithTermCols(cols int) ConsoleOpt { - return func(opts *ConsoleOpts) error { - opts.TermCols = cols - return nil - } -} - -// WithTermRows sets the number of rows in the terminal (Default: 80) -func WithTermRows(rows int) ConsoleOpt { - return func(opts *ConsoleOpts) error { - opts.TermRows = rows - return nil - } -} - -// NewConsole returns a new Console with the given options. -func NewConsole(opts ...ConsoleOpt) (*Console, error) { - options := ConsoleOpts{ - Logger: log.New(ioutil.Discard, "", 0), - TermCols: 80, - TermRows: 30, - } - - for _, opt := range opts { - if err := opt(&options); err != nil { - return nil, err - } - } - - var pty *xpty.Xpty - rows := uint16(options.TermRows) - cols := uint16(options.TermCols) - // On Windows we are adding an extra row, because the last row appears to be empty usually - if runtime.GOOS == "windows" { - rows++ - } - pty, err := xpty.New(cols, rows, true) - if err != nil { - return nil, err - } - - c := &Console{ - opts: options, - Pty: pty, - MatchState: &MatchState{ - TermState: pty.State, - }, - closers: append(options.Closers), - } - - for _, stdin := range options.Stdins { - go func(stdin io.Reader) { - _, err := io.Copy(c, stdin) - if err != nil { - c.Logf("failed to copy stdin: %s", err) - } - }(stdin) - } - - return c, nil -} - -// Tty returns Console's pts (slave part of a pty). A pseudoterminal, or pty is -// a pair of pseudo-devices, one of which, the slave, emulates a real text -// terminal device. -func (c *Console) Tty() *os.File { - return c.Pty.Tty() -} - -// Write writes bytes b to Console's tty. -func (c *Console) Write(b []byte) (int, error) { - c.Logf("console write: %q", b) - return c.Pty.TerminalInPipe().Write(b) -} - -// Fd returns Console's file descripting referencing the master part of its -// pty. -func (c *Console) Fd() uintptr { - return c.Pty.TerminalOutFd() -} - -// CloseReaders closes everything that is trying to read from the terminal -// Call this function once you are sure that you have consumed all bytes -func (c *Console) CloseReaders() (err error) { - for _, fd := range c.closers { - err = fd.Close() - if err != nil { - c.Logf("failed to close: %s", err) - } - } - - return c.Pty.CloseReaders() -} - -// Close closes both the TTY and afterwards all the readers -// You may want to split this up to give the readers time to read all the data -// until they reach the EOF error -func (c *Console) Close() error { - err := c.Pty.CloseTTY() - if err != nil { - c.Logf("failed to close TTY: %v", err) - } - - // close the readers reading from the TTY - return c.CloseReaders() -} - -// Send writes string s to Console's tty. -func (c *Console) Send(s string) (int, error) { - c.Logf("console send: %q", s) - n, err := io.WriteString(c.Pty.TerminalInPipe(), s) - for _, observer := range c.opts.SendObservers { - observer(s, n, err) - } - return n, err -} - -// SendLine writes string s to Console's tty with a trailing newline. -func (c *Console) SendLine(s string) (int, error) { - return c.Send(fmt.Sprintf("%s\n", s)) -} - -// SendOSLine writes string s to Console's tty with a trailing newline separator native to the base OS. -func (c *Console) SendOSLine(s string) (int, error) { - return c.Send(fmt.Sprintf("%s%s", s, osutils.LineSep)) -} - -// Log prints to Console's logger. -// Arguments are handled in the manner of fmt.Print. -func (c *Console) Log(v ...interface{}) { - c.opts.Logger.Print(v...) -} - -// Logf prints to Console's logger. -// Arguments are handled in the manner of fmt.Printf. -func (c *Console) Logf(format string, v ...interface{}) { - c.opts.Logger.Printf(format, v...) -} diff --git a/vendor/github.com/ActiveState/termtest/expect/doc.go b/vendor/github.com/ActiveState/termtest/expect/doc.go deleted file mode 100644 index a0163f0e50..0000000000 --- a/vendor/github.com/ActiveState/termtest/expect/doc.go +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2018 Netflix, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package expect provides an expect-like interface to automate control of -// applications. It is unlike expect in that it does not spawn or manage -// process lifecycle. This package only focuses on expecting output and sending -// input through it's psuedoterminal. -package expect diff --git a/vendor/github.com/ActiveState/termtest/expect/expect.go b/vendor/github.com/ActiveState/termtest/expect/expect.go deleted file mode 100644 index 605ed07999..0000000000 --- a/vendor/github.com/ActiveState/termtest/expect/expect.go +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright 2018 Netflix, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package expect - -import ( - "bufio" - "bytes" - "fmt" - "io" - "time" - "unicode/utf8" -) - -// Expectf reads from the Console's tty until the provided formatted string -// is read or an error occurs, and returns the buffer read by Console. -func (c *Console) Expectf(format string, args ...interface{}) (string, error) { - return c.Expect(String(fmt.Sprintf(format, args...))) -} - -// ExpectString reads from Console's tty until the provided string is read or -// an error occurs, and returns the buffer read by Console. -func (c *Console) ExpectString(s string) (string, error) { - return c.Expect(String(s)) -} - -// ExpectLongString reads from Console's tty until the provided long string is read or -// an error occurs, and returns the buffer read by Console. -// This function ignores mismatches caused by newline and space characters to account -// for wrappings at the maximum terminal width. -func (c *Console) ExpectLongString(s string) (string, error) { - return c.Expect(LongString(s)) -} - -// ExpectEOF reads from Console's tty until EOF or an error occurs, and returns -// the buffer read by Console. We also treat the PTSClosed error as an EOF. -func (c *Console) ExpectEOF() (string, error) { - return c.Expect(PTSClosed, EOF) -} - -// Expect reads from Console's tty until a condition specified from opts is -// encountered or an error occurs, and returns the buffer read by console. -// No extra bytes are read once a condition is met, so if a program isn't -// expecting input yet, it will be blocked. Sends are queued up in tty's -// internal buffer so that the next Expect will read the remaining bytes (i.e. -// rest of prompt) as well as its conditions. -func (c *Console) Expect(opts ...ExpectOpt) (string, error) { - var options ExpectOpts - for _, opt := range opts { - if err := opt(&options); err != nil { - return "", err - } - } - - c.MatchState.Buf = new(bytes.Buffer) - writer := io.MultiWriter(append(c.opts.Stdouts, c.MatchState.Buf)...) - runeWriter := bufio.NewWriterSize(writer, utf8.UTFMax) - - readTimeout := c.opts.ReadTimeout - if options.ReadTimeout != nil { - readTimeout = options.ReadTimeout - } - - var matcher Matcher - var err error - - defer func() { - for _, observer := range c.opts.ExpectObservers { - if matcher != nil { - observer([]Matcher{matcher}, c.MatchState, err) - return - } - observer(options.Matchers, c.MatchState, err) - } - }() - - for { - if readTimeout != nil { - c.Pty.SetReadDeadline(time.Now().Add(*readTimeout)) - } - - var r rune - r, _, err = c.Pty.ReadRune() - if err != nil { - matcher = options.Match(err) - if matcher != nil { - err = nil - break - } - return c.MatchState.Buf.String(), err - } - - c.Logf("expect read: %q", string(r)) - _, err = runeWriter.WriteRune(r) - if err != nil { - return c.MatchState.Buf.String(), err - } - - // Immediately flush rune to the underlying writers. - err = runeWriter.Flush() - if err != nil { - return c.MatchState.Buf.String(), err - } - - matcher = options.Match(c.MatchState) - if matcher != nil { - c.MatchState.markMatch() - break - } - } - - if matcher != nil { - cb, ok := matcher.(CallbackMatcher) - if ok { - err = cb.Callback(c.MatchState) - if err != nil { - return c.MatchState.Buf.String(), err - } - } - } - - return c.MatchState.Buf.String(), err -} diff --git a/vendor/github.com/ActiveState/termtest/expect/expect_opt.go b/vendor/github.com/ActiveState/termtest/expect/expect_opt.go deleted file mode 100644 index aae3fd40c8..0000000000 --- a/vendor/github.com/ActiveState/termtest/expect/expect_opt.go +++ /dev/null @@ -1,386 +0,0 @@ -// Copyright 2018 Netflix, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package expect - -import ( - "io" - "os" - "regexp" - "syscall" - "time" -) - -// ExpectOpt allows settings Expect options. -type ExpectOpt func(*ExpectOpts) error - -// WithTimeout sets a read timeout for an Expect statement. -func WithTimeout(timeout time.Duration) ExpectOpt { - return func(opts *ExpectOpts) error { - opts.ReadTimeout = &timeout - return nil - } -} - -// ConsoleCallback is a callback function to execute if a match is found for -// the chained matcher. -type ConsoleCallback func(ms *MatchState) error - -// Then returns an Expect condition to execute a callback if a match is found -// for the chained matcher. -func (eo ExpectOpt) Then(f ConsoleCallback) ExpectOpt { - return func(opts *ExpectOpts) error { - var options ExpectOpts - err := eo(&options) - if err != nil { - return err - } - - for _, matcher := range options.Matchers { - opts.Matchers = append(opts.Matchers, &callbackMatcher{ - f: f, - matcher: matcher, - }) - } - return nil - } -} - -// ExpectOpts provides additional options on Expect. -type ExpectOpts struct { - Matchers []Matcher - ReadTimeout *time.Duration -} - -// Match sequentially calls Match on all matchers in ExpectOpts and returns the -// first matcher if a match exists, otherwise nil. -func (eo ExpectOpts) Match(v interface{}) Matcher { - for _, matcher := range eo.Matchers { - if matcher.Match(v) { - return matcher - } - } - return nil -} - -// CallbackMatcher is a matcher that provides a Callback function. -type CallbackMatcher interface { - // Callback executes the matcher's callback with the terminal state at the - // time of match. - Callback(matchState *MatchState) error -} - -// Matcher provides an interface for finding a match in content read from -// Console's tty. -type Matcher interface { - // Match returns true iff a match is found. - Match(v interface{}) bool - Criteria() interface{} -} - -// callbackMatcher fulfills the Matcher and CallbackMatcher interface to match -// using its embedded matcher and provide a callback function. -type callbackMatcher struct { - f ConsoleCallback - matcher Matcher -} - -func (cm *callbackMatcher) Match(v interface{}) bool { - return cm.matcher.Match(v) -} - -func (cm *callbackMatcher) Criteria() interface{} { - return cm.matcher.Criteria() -} - -func (cm *callbackMatcher) Callback(ms *MatchState) error { - cb, ok := cm.matcher.(CallbackMatcher) - if ok { - err := cb.Callback(ms) - if err != nil { - return err - } - } - err := cm.f(ms) - if err != nil { - return err - } - return nil -} - -// errorMatcher fulfills the Matcher interface to match a specific error. -type errorMatcher struct { - err error -} - -func (em *errorMatcher) Match(v interface{}) bool { - err, ok := v.(error) - if !ok { - return false - } - return err == em.err -} - -func (em *errorMatcher) Criteria() interface{} { - return em.err -} - -// pathErrorMatcher fulfills the Matcher interface to match a specific os.PathError. -type pathErrorMatcher struct { - pathError os.PathError -} - -func (em *pathErrorMatcher) Match(v interface{}) bool { - pathError, ok := v.(*os.PathError) - if !ok { - return false - } - expected := em.pathError - if expected.Path == "" { - expected.Path = pathError.Path - } - return *pathError == expected -} - -func (em *pathErrorMatcher) Criteria() interface{} { - return em.pathError -} - -type anyMatcher struct { - options ExpectOpts -} - -func (om *anyMatcher) Match(v interface{}) bool { - for _, matcher := range om.options.Matchers { - if matcher.Match(v) { - return true - } - } - return false -} - -func (om *anyMatcher) Criteria() interface{} { - var criterias []interface{} - for _, matcher := range om.options.Matchers { - criterias = append(criterias, matcher.Criteria()) - } - return criterias -} - -// stringMatcher fulfills the Matcher interface to match strings against a given -// MatchState -type stringMatcher struct { - str string - ignoreNewlinesAndSpaces bool -} - -func (sm *stringMatcher) Match(v interface{}) bool { - ms, ok := v.(*MatchState) - if !ok { - return false - } - return ms.TermState.HasStringBeforeCursor(sm.str, sm.ignoreNewlinesAndSpaces) -} - -func (sm *stringMatcher) Criteria() interface{} { - return sm.str -} - -// regexpMatcher fulfills the Matcher interface to match Regexp against a given -// MatchState. -type regexpMatcher struct { - re *regexp.Regexp -} - -func (rm *regexpMatcher) Match(v interface{}) bool { - ms, ok := v.(*MatchState) - if !ok { - return false - } - return rm.re.MatchString(ms.UnwrappedStringToCursorFromMatch(0)) -} - -func (rm *regexpMatcher) Criteria() interface{} { - return rm.re -} - -// allMatcher fulfills the Matcher interface to match a group of ExpectOpt -// against any value. -type allMatcher struct { - options ExpectOpts -} - -func (am *allMatcher) Match(v interface{}) bool { - var matchers []Matcher - for _, matcher := range am.options.Matchers { - if matcher.Match(v) { - continue - } - matchers = append(matchers, matcher) - } - - am.options.Matchers = matchers - return len(matchers) == 0 -} - -func (am *allMatcher) Criteria() interface{} { - var criterias []interface{} - for _, matcher := range am.options.Matchers { - criterias = append(criterias, matcher.Criteria()) - } - return criterias -} - -// All adds an Expect condition to exit if the content read from Console's tty -// matches all of the provided ExpectOpt, in any order. -func All(expectOpts ...ExpectOpt) ExpectOpt { - return func(opts *ExpectOpts) error { - var options ExpectOpts - for _, opt := range expectOpts { - if err := opt(&options); err != nil { - return err - } - } - - opts.Matchers = append(opts.Matchers, &allMatcher{ - options: options, - }) - return nil - } -} - -// String adds an Expect condition to exit if the content read from Console's -// tty contains any of the given strings. -func String(strs ...string) ExpectOpt { - return func(opts *ExpectOpts) error { - for _, str := range strs { - opts.Matchers = append(opts.Matchers, &stringMatcher{ - str: str, - }) - } - return nil - } -} - -// LongString adds an Expect condition to exit if the content read from Console's -// tty contains any of the given long strings ignoring newlines and spaces to account -// for potential automatic wrappings at the terminal width. -func LongString(strs ...string) ExpectOpt { - return func(opts *ExpectOpts) error { - for _, str := range strs { - opts.Matchers = append(opts.Matchers, &stringMatcher{ - str: str, - ignoreNewlinesAndSpaces: true, - }) - } - return nil - } -} - -// Regexp adds an Expect condition to exit if the content read from Console's -// tty matches the given Regexp. -func Regexp(res ...*regexp.Regexp) ExpectOpt { - return func(opts *ExpectOpts) error { - for _, re := range res { - opts.Matchers = append(opts.Matchers, ®expMatcher{ - re: re, - }) - } - return nil - } -} - -// RegexpPattern adds an Expect condition to exit if the content read from -// Console's tty matches the given Regexp patterns. Expect returns an error if -// the patterns were unsuccessful in compiling the Regexp. -func RegexpPattern(ps ...string) ExpectOpt { - return func(opts *ExpectOpts) error { - var res []*regexp.Regexp - for _, p := range ps { - re, err := regexp.Compile(p) - if err != nil { - return err - } - res = append(res, re) - } - return Regexp(res...)(opts) - } -} - -// Error adds an Expect condition to exit if reading from Console's tty returns -// one of the provided errors. -func Error(errs ...error) ExpectOpt { - return func(opts *ExpectOpts) error { - for _, err := range errs { - opts.Matchers = append(opts.Matchers, &errorMatcher{ - err: err, - }) - } - return nil - } -} - -// EOF adds an Expect condition to exit if io.EOF is returned from reading -// Console's tty. -func EOF(opts *ExpectOpts) error { - return Error(io.EOF)(opts) -} - -// PTSClosed adds an Expect condition to exit if we get an -// "read /dev/ptmx: input/output error" error which can occur -// on Linux while reading from the ptm after the pts is closed. -// Further Reading: -// https://github.com/kr/pty/issues/21#issuecomment-129381749 -func PTSClosed(opts *ExpectOpts) error { - opts.Matchers = append(opts.Matchers, &pathErrorMatcher{ - pathError: os.PathError{ - Op: "read", - Path: "/dev/ptmx", - Err: syscall.Errno(0x5), - }, - }) - return nil -} - -// StdinClosed adds an Expect condition to exit if we read from -// stdin after it has been closed which can occur on Windows while -// reading from the Pseudo-terminal after it is closed -func StdinClosed(opts *ExpectOpts) error { - opts.Matchers = append(opts.Matchers, &pathErrorMatcher{ - pathError: os.PathError{ - Op: "read", - Path: "", - Err: os.ErrClosed, - }, - }) - return nil -} - -// Any adds an Expect condition to exit if the content read from Console's tty -// matches any of the provided ExpectOpt -func Any(expectOpts ...ExpectOpt) ExpectOpt { - return func(opts *ExpectOpts) error { - var options ExpectOpts - for _, opt := range expectOpts { - if err := opt(&options); err != nil { - return err - } - } - - opts.Matchers = append(opts.Matchers, &anyMatcher{ - options: options, - }) - return nil - } -} diff --git a/vendor/github.com/ActiveState/termtest/expect/internal/osutils/linesep.go b/vendor/github.com/ActiveState/termtest/expect/internal/osutils/linesep.go deleted file mode 100644 index aa628bccae..0000000000 --- a/vendor/github.com/ActiveState/termtest/expect/internal/osutils/linesep.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2020 ActiveState Software, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// +build linux darwin - -package osutils - -// LineSep is the line separator character string used on the GOOS -var LineSep = "\n" diff --git a/vendor/github.com/ActiveState/termtest/expect/internal/osutils/linesep_windows.go b/vendor/github.com/ActiveState/termtest/expect/internal/osutils/linesep_windows.go deleted file mode 100644 index d60bbbbc5a..0000000000 --- a/vendor/github.com/ActiveState/termtest/expect/internal/osutils/linesep_windows.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2020 ActiveState Software, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// +build windows - -package osutils - -// LineSep is the line separator character string used on the GOOS -var LineSep = "\r\n" diff --git a/vendor/github.com/ActiveState/termtest/expect/test_log.go b/vendor/github.com/ActiveState/termtest/expect/test_log.go deleted file mode 100644 index 13ed15a1cc..0000000000 --- a/vendor/github.com/ActiveState/termtest/expect/test_log.go +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright 2018 Netflix, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package expect - -import ( - "bufio" - "io" - "strings" - "testing" -) - -// NewTestConsole returns a new Console that multiplexes the application's -// stdout to go's testing logger. Primarily so that outputs from parallel tests -// using t.Parallel() is not interleaved. -func NewTestConsole(t *testing.T, opts ...ConsoleOpt) (*Console, error) { - tf, err := NewTestWriter(t) - if err != nil { - return nil, err - } - - return NewConsole(append(opts, WithStdout(tf))...) -} - -// NewTestWriter returns an io.Writer where bytes written to the file are -// logged by go's testing logger. Bytes are flushed to the logger on line end. -func NewTestWriter(t *testing.T) (io.Writer, error) { - r, w := io.Pipe() - tw := testWriter{t} - - go func() { - defer r.Close() - - br := bufio.NewReader(r) - - for { - line, _, err := br.ReadLine() - if err != nil { - if err != io.EOF { - t.Logf("Unexpected error reading line: %v\n", err) - } - return - } - - _, err = tw.Write(line) - if err != nil { - t.Logf("Unexpected writing to testWriter: %v\n", err) - return - } - } - }() - - return w, nil -} - -// testWriter provides a io.Writer interface to go's testing logger. -type testWriter struct { - t *testing.T -} - -func (tw testWriter) Write(p []byte) (n int, err error) { - tw.t.Log(string(p)) - return len(p), nil -} - -// StripTrailingEmptyLines returns a copy of s stripped of trailing lines that -// consist of only space characters. -func StripTrailingEmptyLines(out string) string { - lines := strings.Split(out, "\n") - if len(lines) < 2 { - return out - } - - for i := len(lines) - 1; i >= 0; i-- { - stripped := strings.Replace(lines[i], " ", "", -1) - if len(stripped) == 0 { - lines = lines[:len(lines)-1] - } else { - break - } - } - - return strings.Join(lines, "\n") -} diff --git a/vendor/github.com/ActiveState/termtest/helpers.go b/vendor/github.com/ActiveState/termtest/helpers.go new file mode 100644 index 0000000000..2bb0615df6 --- /dev/null +++ b/vendor/github.com/ActiveState/termtest/helpers.go @@ -0,0 +1,82 @@ +package termtest + +import ( + "bytes" + "errors" + "os" + "os/exec" + "strings" + "time" +) + +type voidWriter struct{} + +func (v voidWriter) Write(p []byte) (n int, err error) { return len(p), nil } + +var neverGonnaHappen = time.Hour * 24 * 365 * 100 + +var lineSepPosix = "\n" +var lineSepWindows = "\r\n" + +type cmdExit struct { + ProcessState *os.ProcessState + Err error +} + +// waitForCmdExit turns process.wait() into a channel so that it can be used within a select{} statement +func waitForCmdExit(cmd *exec.Cmd) chan cmdExit { + exit := make(chan cmdExit, 1) + go func() { + err := cmd.Wait() + exit <- cmdExit{ProcessState: cmd.ProcessState, Err: err} + }() + return exit +} + +func waitChan[T any](wait func() T) chan T { + done := make(chan T) + go func() { + wait() + close(done) + }() + return done +} + +// getIndex returns the given index from the given slice, or the fallback if the index does not exist +func getIndex[T any](v []T, i int, fallback T) T { + if i > len(v)-1 { + return fallback + } + return v[i] +} + +func unwrapErrorMessage(err error) string { + msg := []string{} + for err != nil { + msg = append(msg, err.Error()) + err = errors.Unwrap(err) + } + + // Reverse the slice so that the most inner error is first + reverse(msg) + + return strings.Join(msg, " -> ") +} + +func reverse[S ~[]E, E any](s S) { + for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 { + s[i], s[j] = s[j], s[i] + } +} + +func NormalizeLineEnds(v string) string { + return strings.ReplaceAll(v, "\r", "") +} + +func NormalizeLineEndsB(v []byte) []byte { + return bytes.ReplaceAll(v, []byte("\r"), []byte("")) +} + +func copyBytes(b []byte) []byte { + return append([]byte{}, b...) +} diff --git a/vendor/github.com/ActiveState/termtest/helpers_unix.go b/vendor/github.com/ActiveState/termtest/helpers_unix.go new file mode 100644 index 0000000000..5034992680 --- /dev/null +++ b/vendor/github.com/ActiveState/termtest/helpers_unix.go @@ -0,0 +1,14 @@ +//go:build !windows +// +build !windows + +package termtest + +import ( + "errors" +) + +var ERR_ACCESS_DENIED = errors.New("only used on windows, this should never match") + +func cleanPtySnapshot(b []byte, cursorPos int, _ bool) ([]byte, int) { + return b, cursorPos +} diff --git a/vendor/github.com/ActiveState/termtest/helpers_windows.go b/vendor/github.com/ActiveState/termtest/helpers_windows.go new file mode 100644 index 0000000000..b466ff5108 --- /dev/null +++ b/vendor/github.com/ActiveState/termtest/helpers_windows.go @@ -0,0 +1,111 @@ +package termtest + +import ( + "bytes" + + "golang.org/x/sys/windows" +) + +var ERR_ACCESS_DENIED = windows.ERROR_ACCESS_DENIED + +const UnicodeEscapeRune = '\u001B' +const UnicodeBellRune = '\u0007' +const UnicodeBackspaceRune = '\u0008' // Note in the docs this is \u007f, but in actual use we're seeing \u0008. Possibly badly documented. + +// cleanPtySnapshot removes windows console escape sequences from the output so we can interpret it plainly. +// Ultimately we want to emulate the windows console here, just like we're doing for v10x on posix. +// The current implementation is geared towards our needs, and won't be able to handle all escape sequences as a result. +// For details on escape sequences see https://learn.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences +func cleanPtySnapshot(snapshot []byte, cursorPos int, isPosix bool) ([]byte, int) { + if isPosix { + return snapshot, cursorPos + } + + // Most escape sequences appear to end on `A-Za-z@` + plainVirtualEscapeSeqEndValues := []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz@") + + // Cheaper than converting to ints + numbers := []byte("0123456789") + + // Some escape sequences are more complex, such as window titles + recordingCode := false + escapeSequenceCode := "" + inEscapeSequence := false + inTitleEscapeSequence := false + + newCursorPos := cursorPos + dropPos := func(pos int) { + if pos <= cursorPos { + newCursorPos-- + } + } + + var result []rune + runes := bytes.Runes(snapshot) + for pos, r := range runes { + // Reset code recording outside of escape sequence, so we don't have to manually handle this throughout + if !inEscapeSequence { + recordingCode = false + escapeSequenceCode = "" + } + switch { + // SEQUENCE START + + // Detect start of escape sequence + case !inEscapeSequence && r == UnicodeEscapeRune: + inEscapeSequence = true + recordingCode = true + dropPos(pos) + continue + + // Detect start of complex escape sequence + case inEscapeSequence && !inTitleEscapeSequence && (escapeSequenceCode == "0" || escapeSequenceCode == "2"): + inTitleEscapeSequence = true + recordingCode = false + dropPos(pos) + continue + + // SEQUENCE END + + // Detect end of escape sequence + case inEscapeSequence && !inTitleEscapeSequence && bytes.ContainsRune(plainVirtualEscapeSeqEndValues, r): + inEscapeSequence = false + dropPos(pos) + continue + + // Detect end of complex escape sequence + case inTitleEscapeSequence && r == UnicodeBellRune: + inEscapeSequence = false + inTitleEscapeSequence = false + dropPos(pos) + continue + + // SEQUENCE CONTINUATION + + case inEscapeSequence && recordingCode && bytes.ContainsRune(numbers, r): + escapeSequenceCode += string(r) + dropPos(pos) + continue + + // Detect continuation of escape sequence + case inEscapeSequence: + if r != ']' { + recordingCode = false + } + dropPos(pos) + continue + + // OUTSIDE OF ESCAPE SEQUENCE + + case r == UnicodeBackspaceRune && len(result) > 0: + dropPos(pos - 1) + dropPos(pos) + result = result[:len(result)-1] + continue + + default: + result = append(result, r) + } + } + return []byte(string(result)), newCursorPos +} diff --git a/vendor/github.com/ActiveState/termtest/internal/osutils/osutils.go b/vendor/github.com/ActiveState/termtest/internal/osutils/osutils.go deleted file mode 100644 index ed6f944c72..0000000000 --- a/vendor/github.com/ActiveState/termtest/internal/osutils/osutils.go +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2020 ActiveState Software. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file - -package osutils - -import ( - "os/exec" - "strings" -) - -// This is a copy of the Go 1.13 (cmd.String) function -func CmdString(c *exec.Cmd) string { - - // report the exact executable path (plus args) - b := new(strings.Builder) - b.WriteString(c.Path) - - for _, a := range c.Args[1:] { - b.WriteByte(' ') - b.WriteString(a) - } - - return b.String() -} diff --git a/vendor/github.com/ActiveState/termtest/internal/osutils/process_posix.go b/vendor/github.com/ActiveState/termtest/internal/osutils/process_posix.go deleted file mode 100644 index c5735bc86f..0000000000 --- a/vendor/github.com/ActiveState/termtest/internal/osutils/process_posix.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2020 ActiveState Software. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file - -// +build linux darwin - -package osutils - -import "syscall" - -// SysProcAttrForNewProcessGroup returns a SysProcAttr structure configured to start a process with a new process group -func SysProcAttrForNewProcessGroup() *syscall.SysProcAttr { - return &syscall.SysProcAttr{ - Setsid: true, - } -} diff --git a/vendor/github.com/ActiveState/termtest/internal/osutils/process_windows.go b/vendor/github.com/ActiveState/termtest/internal/osutils/process_windows.go deleted file mode 100644 index 37a567d245..0000000000 --- a/vendor/github.com/ActiveState/termtest/internal/osutils/process_windows.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2020 ActiveState Software. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file - -// +build windows - -package osutils - -import "syscall" - -// SysProcAttrForNewProcessGroup returns a SysProcAttr structure configured to start a process with a new process group -func SysProcAttrForNewProcessGroup() *syscall.SysProcAttr { - return &syscall.SysProcAttr{ - CreationFlags: 0x00000200, // CREATE_NEW_PROCESS_GROUP - } -} diff --git a/vendor/github.com/ActiveState/termtest/internal/osutils/stacktrace/stacktrace.go b/vendor/github.com/ActiveState/termtest/internal/osutils/stacktrace/stacktrace.go deleted file mode 100644 index a3e0177efd..0000000000 --- a/vendor/github.com/ActiveState/termtest/internal/osutils/stacktrace/stacktrace.go +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright 2020 ActiveState Software. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file - -package stacktrace - -import ( - "fmt" - "path/filepath" - "runtime" - "strings" -) - -// Stacktrace represents a stacktrace -type Stacktrace struct { - Frames []Frame -} - -// Frame is a single frame in a stacktrace -type Frame struct { - // Func contains a function name. - Func string - // Line contains a line number. - Line int - // Path contains a file path. - Path string - // Package is the package name for this frame - Package string -} - -// FrameCap is a default cap for frames array. -// It can be changed to number of expected frames -// for purpose of performance optimisation. -var FrameCap = 20 - -// String returns a string representation of a stacktrace -func (t *Stacktrace) String() string { - result := []string{} - for _, frame := range t.Frames { - result = append(result, fmt.Sprintf(`%s:%s:%d`, frame.Path, frame.Func, frame.Line)) - } - return strings.Join(result, "\n") -} - -// Get returns a stacktrace -func Get() *Stacktrace { - stacktrace := &Stacktrace{} - pc := make([]uintptr, FrameCap) - n := runtime.Callers(1, pc) - if n == 0 { - return stacktrace - } - - pc = pc[:n] - frames := runtime.CallersFrames(pc) - - var skipFile, skipPkg string - for { - frame, more := frames.Next() - pkg := strings.Split(filepath.Base(frame.Func.Name()), ".")[0] - - // Skip our own path - if skipFile == "" { - skipFile = filepath.Dir(frame.File) - skipPkg = pkg - } - if strings.Contains(frame.File, skipFile) && pkg == skipPkg { - continue - } - - stacktrace.Frames = append(stacktrace.Frames, Frame{ - Func: frame.Func.Name(), - Line: frame.Line, - Path: frame.File, - Package: pkg, - }) - - if !more { - break - } - } - - return stacktrace -} diff --git a/vendor/github.com/ActiveState/termtest/opts.go b/vendor/github.com/ActiveState/termtest/opts.go deleted file mode 100644 index 497cfa3683..0000000000 --- a/vendor/github.com/ActiveState/termtest/opts.go +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2020 ActiveState Software. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file - -package termtest - -import ( - "io/ioutil" - "os" - "time" - - expect "github.com/ActiveState/termtest/expect" -) - -// SendObserver is function that is called when text is send to the console -// Arguments are the message, number of bytes written and an error message -// See TestSendObserveFn for an example -type SendObserver func(msg string, num int, err error) - -// Options contain optional values for ConsoleProcess construction and usage. -type Options struct { - DefaultTimeout time.Duration - WorkDirectory string - RetainWorkDir bool - Environment []string - ObserveSend SendObserver - ObserveExpect expect.ExpectObserver - CmdName string - Args []string - HideCmdLine bool - ExtraOpts []expect.ConsoleOpt -} - -// Normalize fills in default options -func (opts *Options) Normalize() error { - if opts.DefaultTimeout == 0 { - opts.DefaultTimeout = time.Second * 20 - } - - if opts.WorkDirectory == "" { - tmpDir, err := ioutil.TempDir("", "") - if err != nil { - return err - } - opts.WorkDirectory = tmpDir - } - - if opts.ObserveSend == nil { - opts.ObserveSend = func(string, int, error) {} - } - - if opts.ObserveExpect == nil { - opts.ObserveExpect = func([]expect.Matcher, *expect.MatchState, error) {} - } - - return nil -} - -// CleanUp cleans up the environment -func (opts *Options) CleanUp() error { - if !opts.RetainWorkDir { - return os.RemoveAll(opts.WorkDirectory) - } - - return nil -} diff --git a/vendor/github.com/ActiveState/termtest/outputconsumer.go b/vendor/github.com/ActiveState/termtest/outputconsumer.go new file mode 100644 index 0000000000..1665e4b1a6 --- /dev/null +++ b/vendor/github.com/ActiveState/termtest/outputconsumer.go @@ -0,0 +1,105 @@ +package termtest + +import ( + "fmt" + "sync" + "time" +) + +type consumer func(buffer string) (matchEndPos int, err error) + +type outputConsumer struct { + _test_id string // for testing purposes only, not used for non-testing logic + consume consumer + waiter chan error + opts *OutputConsumerOpts + isalive bool + mutex *sync.Mutex +} + +type OutputConsumerOpts struct { + *Opts + Timeout time.Duration +} + +type SetConsOpt func(o *OutputConsumerOpts) + +func OptConsInherit(o *Opts) func(o *OutputConsumerOpts) { + return func(oco *OutputConsumerOpts) { + oco.Opts = o + } +} + +func OptsConsTimeout(timeout time.Duration) func(o *OutputConsumerOpts) { + return func(oco *OutputConsumerOpts) { + oco.Timeout = timeout + } +} + +func newOutputConsumer(consume consumer, opts ...SetConsOpt) *outputConsumer { + oc := &outputConsumer{ + consume: consume, + opts: &OutputConsumerOpts{ + Opts: NewOpts(), + Timeout: 5 * time.Second, // Default timeout + }, + waiter: make(chan error, 1), + isalive: true, + mutex: &sync.Mutex{}, + } + + for _, optSetter := range opts { + optSetter(oc.opts) + } + + return oc +} + +func (e *outputConsumer) IsAlive() bool { + return e.isalive +} + +// Report will consume the given buffer and will block unless wait() has been called +func (e *outputConsumer) Report(buffer []byte) (int, error) { + e.mutex.Lock() + defer e.mutex.Unlock() + + pos, err := e.consume(string(buffer)) + if err != nil { + err = fmt.Errorf("consumer threw error: %w", err) + } + if err == nil && pos > len(buffer) { + err = fmt.Errorf("consumer returned endPos %d which is greater than buffer length %d", pos, len(buffer)) + } + if err != nil || pos > 0 { + e.opts.Logger.Printf("closing waiter from report, err: %v, endPos: %d\n", err, pos) + // This prevents report() from blocking in case wait() has not been called yet + go func() { + e.waiter <- err + }() + } + return pos, err +} + +func (e *outputConsumer) wait() error { + e.opts.Logger.Println("started waiting") + defer e.opts.Logger.Println("stopped waiting") + + defer func() { + e.isalive = false + e.mutex.Unlock() + }() + + select { + case err := <-e.waiter: + e.mutex.Lock() + if err != nil { + e.opts.Logger.Printf("Encountered error: %s\n", err.Error()) + } + return err + case <-time.After(e.opts.Timeout): + e.mutex.Lock() + e.opts.Logger.Println("Encountered timeout") + return fmt.Errorf("after %s: %w", e.opts.Timeout, TimeoutError) + } +} diff --git a/vendor/github.com/ActiveState/termtest/outputproducer.go b/vendor/github.com/ActiveState/termtest/outputproducer.go new file mode 100644 index 0000000000..34ae967d60 --- /dev/null +++ b/vendor/github.com/ActiveState/termtest/outputproducer.go @@ -0,0 +1,262 @@ +package termtest + +import ( + "bufio" + "bytes" + "errors" + "fmt" + "io" + "io/fs" + "runtime" + "sync" + "time" +) + +// producerPollInterval is the interval at which the output producer will poll the pty for new output +const producerPollInterval = 100 * time.Millisecond + +// producerBufferSize is the maximum size of the snapshot buffer that we read on each interval +const producerBufferSize = 1024 + +// outputProducer is responsible for keeping track of the output and notifying consumers when new output is produced +type outputProducer struct { + output []byte + cursorPos int // The position of our virtual cursor, which is the position up to where we've satisfied consumers + cleanUptoPos int // Up to which position we've cleaned the output, because incomplete output cannot be cleaned + consumers []*outputConsumer + opts *Opts + mutex *sync.Mutex +} + +func newOutputProducer(opts *Opts) *outputProducer { + return &outputProducer{ + output: []byte{}, + consumers: []*outputConsumer{}, + opts: opts, + mutex: &sync.Mutex{}, + } +} + +func (o *outputProducer) Listen(r io.Reader, w io.Writer) error { + return o.listen(r, w, o.appendBuffer, producerPollInterval, producerBufferSize) +} + +func (o *outputProducer) listen(r io.Reader, w io.Writer, appendBuffer func([]byte, bool) error, interval time.Duration, size int) (rerr error) { + o.opts.Logger.Println("listen started") + defer func() { + o.opts.Logger.Printf("listen stopped, err: %v\n", rerr) + }() + + br := bufio.NewReader(r) + + // Most of the actual logic is in processNextRead, all we're doing here is looping and signaling ready after the first + // iteration + for { + o.opts.Logger.Println("listen: loop") + if err := o.processNextRead(br, w, appendBuffer, size); err != nil { + if errors.Is(err, ptyEOF) { + o.opts.Logger.Println("listen: reached EOF") + return nil + } else { + return fmt.Errorf("could not poll reader: %w", err) + } + } + } +} + +var ptyEOF = errors.New("pty closed") + +func (o *outputProducer) processNextRead(r io.Reader, w io.Writer, appendBuffer func([]byte, bool) error, size int) error { + o.opts.Logger.Printf("processNextRead started with size: %d\n", size) + defer o.opts.Logger.Println("processNextRead stopped") + + snapshot := make([]byte, size) + n, errRead := r.Read(snapshot) + + isEOF := false + if errRead != nil { + pathError := &fs.PathError{} + if errors.Is(errRead, fs.ErrClosed) || errors.Is(errRead, io.EOF) || (runtime.GOOS == "linux" && errors.As(errRead, &pathError)) { + isEOF = true + } + } + + if n > 0 { + o.opts.Logger.Printf("outputProducer read %d bytes from pty, value: %#v", n, string(snapshot[:n])) + if _, err := w.Write(snapshot[:n]); err != nil { + return fmt.Errorf("could not write: %w", err) + } + } + + if n > 0 || isEOF { + if err := appendBuffer(snapshot[:n], isEOF); err != nil { + return fmt.Errorf("could not append buffer: %w", err) + } + } + + if errRead != nil { + if isEOF { + return errors.Join(errRead, ptyEOF) + } + return fmt.Errorf("could not read pty output: %w", errRead) + } + + return nil +} + +func (o *outputProducer) appendBuffer(value []byte, isFinal bool) error { + o.opts.Logger.Printf("appendBuffer called with %d bytes, isFinal=%v", len(value), isFinal) + if o.opts.NormalizedLineEnds { + o.opts.Logger.Println("NormalizedLineEnds prior to appendBuffer") + value = NormalizeLineEndsB(value) + } + + output := append(o.output, value...) + + // Clean output + var err error + o.output, o.cursorPos, o.cleanUptoPos, err = o.processDirtyOutput(output, o.cursorPos, o.cleanUptoPos, isFinal, func(output []byte, cursorPos int) ([]byte, int, error) { + var err error + output, cursorPos = cleanPtySnapshot(output, cursorPos, o.opts.Posix) + if o.opts.OutputSanitizer != nil { + output, cursorPos, err = o.opts.OutputSanitizer(output, cursorPos) + } + return output, cursorPos, err + }) + if err != nil { + return fmt.Errorf("cleaning output failed: %w", err) + } + + o.opts.Logger.Printf("flushing %d output consumers", len(o.consumers)) + defer o.opts.Logger.Println("flushed output consumers") + + if err := o.flushConsumers(); err != nil { + return fmt.Errorf("could not flush consumers: %w", err) + } + + return nil +} + +type cleanerFunc func([]byte, int) ([]byte, int, error) + +// processDirtyOutput will sanitize the output received, but we have to be careful not to clean output that hasn't fully arrived +// For example we may be inside an escape sequence and the escape sequence hasn't finished +// So instead we only process new output up to the most recent line break +// In order for this to work properly the invoker must ensure the output and cleanUptoPos are consistent with each other. +func (o *outputProducer) processDirtyOutput(output []byte, cursorPos int, cleanUptoPos int, isFinal bool, cleaner cleanerFunc) (_output []byte, _cursorPos int, _cleanUptoPos int, _err error) { + defer func() { + o.opts.Logger.Printf("Cleaned output from %d to %d\n", cleanUptoPos, _cleanUptoPos) + }() + alreadyCleanedOutput := copyBytes(output[:cleanUptoPos]) + processedOutput := []byte{} + unprocessedOutput := copyBytes(output[cleanUptoPos:]) + processedCursorPos := cursorPos - len(alreadyCleanedOutput) + + if isFinal { + // If we've reached the end there's no point looking for the most recent line break as there's no guarantee the + // output will be terminated by a newline. + processedOutput = copyBytes(unprocessedOutput) + unprocessedOutput = []byte{} + } else { + // Find the most recent line break, and only clean until that point. + // Any output after the most recent line break is considered not ready for cleaning as cleaning depends on + // multiple consecutive characters. + lineSepN := bytes.LastIndex(unprocessedOutput, []byte("\n")) + if lineSepN != -1 { + processedOutput = copyBytes(unprocessedOutput[0 : lineSepN+1]) + unprocessedOutput = unprocessedOutput[lineSepN+1:] + } + } + + // Invoke the cleaner now that we have output that can be cleaned + if len(processedOutput) > 0 { + var err error + processedOutput, processedCursorPos, err = cleaner(processedOutput, processedCursorPos) + if err != nil { + return processedOutput, processedCursorPos, cleanUptoPos, fmt.Errorf("cleaner failed: %w", err) + } + } + + // Convert cursor position back to absolute + processedCursorPos += len(alreadyCleanedOutput) + + if processedCursorPos < 0 { + // Because the cleaner function needs to support a negative cursor position it is impossible for the cleaner + // to know when they've reached the start of the output, so we need to facilitate it here. + // Alternatively we could teach the cleaner about its absolute position, so it can handle this. + processedCursorPos = 0 + } + + // Keep a record of what point we're up to + newCleanUptoPos := cleanUptoPos + len(processedOutput) + + // Stitch everything back together + return append(append(alreadyCleanedOutput, processedOutput...), unprocessedOutput...), processedCursorPos, newCleanUptoPos, nil +} + +func (o *outputProducer) flushConsumers() error { + o.opts.Logger.Println("flushing consumers") + defer o.opts.Logger.Println("flushed consumers") + + o.mutex.Lock() + defer o.mutex.Unlock() + + for n := 0; n < len(o.consumers); n++ { + consumer := o.consumers[n] + snapshot := o.PendingOutput() // o.PendingOutput() considers the cursorPos + if len(snapshot) == 0 { + o.opts.Logger.Println("no snapshot to flush") + return nil + } + + if !consumer.IsAlive() { + o.opts.Logger.Printf("dropping consumer %d out of %d as it is no longer alive", n, len(o.consumers)) + o.consumers = append(o.consumers[:n], o.consumers[n+1:]...) + n-- + continue + } + + endPos, err := consumer.Report(snapshot) + o.opts.Logger.Printf("consumer reported endpos: %d, err: %v", endPos, err) + if err != nil { + return fmt.Errorf("consumer threw error: %w", err) + } + + if endPos > 0 { + if endPos > len(snapshot) { + return fmt.Errorf("consumer reported end position %d greater than snapshot length %d", endPos, len(o.output)) + } + o.cursorPos += endPos + + // Drop consumer + o.opts.Logger.Printf("dropping consumer %d out of %d", n+1, len(o.consumers)) + o.consumers = append(o.consumers[:n], o.consumers[n+1:]...) + n-- + } + } + + return nil +} + +func (o *outputProducer) addConsumer(consume consumer, opts ...SetConsOpt) (*outputConsumer, error) { + o.opts.Logger.Printf("adding consumer") + defer o.opts.Logger.Printf("added consumer") + + opts = append(opts, OptConsInherit(o.opts)) + listener := newOutputConsumer(consume, opts...) + o.consumers = append(o.consumers, listener) + + if err := o.flushConsumers(); err != nil { + return nil, fmt.Errorf("could not flush consumers: %w", err) + } + + return listener, nil +} + +func (o *outputProducer) PendingOutput() []byte { + return o.output[o.cursorPos:] +} + +func (o *outputProducer) Output() []byte { + return o.output +} diff --git a/vendor/github.com/ActiveState/termtest/termtest.go b/vendor/github.com/ActiveState/termtest/termtest.go new file mode 100644 index 0000000000..66481e8165 --- /dev/null +++ b/vendor/github.com/ActiveState/termtest/termtest.go @@ -0,0 +1,315 @@ +package termtest + +import ( + "errors" + "fmt" + "log" + "os" + "os/exec" + "runtime" + "runtime/debug" + "sync" + "testing" + "time" + + "github.com/ActiveState/pty" + "github.com/hinshun/vt10x" +) + +// TermTest bonds a command with a pseudo-terminal for automation +type TermTest struct { + cmd *exec.Cmd + term vt10x.Terminal + ptmx pty.Pty + outputProducer *outputProducer + listenError chan error + opts *Opts +} + +type ErrorHandler func(*TermTest, error) error + +type Opts struct { + Logger *log.Logger + ExpectErrorHandler ErrorHandler + Cols int + Rows int + Posix bool + DefaultTimeout time.Duration + OutputSanitizer cleanerFunc + NormalizedLineEnds bool +} + +var TimeoutError = errors.New("timeout") + +type SetOpt func(o *Opts) error + +const DefaultCols = 140 +const DefaultRows = 10 + +func NewOpts() *Opts { + return &Opts{ + Logger: log.New(voidWriter{}, "TermTest: ", log.LstdFlags|log.Lshortfile), + ExpectErrorHandler: func(_ *TermTest, err error) error { + panic(err) + }, + Cols: DefaultCols, + Rows: DefaultRows, + Posix: runtime.GOOS != "windows", + DefaultTimeout: 5 * time.Second, + } +} + +func New(cmd *exec.Cmd, opts ...SetOpt) (*TermTest, error) { + optv := NewOpts() + for _, setOpt := range opts { + if err := setOpt(optv); err != nil { + return nil, fmt.Errorf("could not set option: %w", err) + } + } + + t := &TermTest{ + cmd: cmd, + outputProducer: newOutputProducer(optv), + listenError: make(chan error, 1), + opts: optv, + } + + if err := t.start(); err != nil { + return nil, fmt.Errorf("could not start: %w", err) + } + + return t, nil +} + +func TestErrorHandler(t *testing.T) ErrorHandler { + return func(tt *TermTest, err error) error { + t.Errorf("Error encountered: %s\nOutput: %s\nStack: %s", unwrapErrorMessage(err), tt.Output(), debug.Stack()) + return err + } +} + +func SilenceErrorHandler() ErrorHandler { + return func(_ *TermTest, err error) error { + return err + } +} + +func OptVerboseLogging() SetOpt { + return func(o *Opts) error { + o.Logger = log.New(os.Stderr, "TermTest: ", log.LstdFlags|log.Lshortfile) + return nil + } +} + +type testLogger struct { + t *testing.T +} + +func (l *testLogger) Write(p []byte) (n int, err error) { + l.t.Log(string(p)) + return len(p), nil +} + +func OptSetTest(t *testing.T) SetOpt { + return func(o *Opts) error { + setTest(o, t) + return nil + } +} + +func OptErrorHandler(handler ErrorHandler) SetOpt { + return func(o *Opts) error { + o.ExpectErrorHandler = handler + return nil + } +} + +func OptTestErrorHandler(t *testing.T) SetOpt { + return OptErrorHandler(TestErrorHandler(t)) +} + +func OptCols(cols int) SetOpt { + return func(o *Opts) error { + o.Cols = cols + return nil + } +} + +// OptRows sets the number of rows for the pty, increase this if you find your output appears to stop prematurely +// appears to only make a difference on Windows. Linux/Mac will happily function with a single row +func OptRows(rows int) SetOpt { + return func(o *Opts) error { + o.Rows = rows + return nil + } +} + +func OptSilenceErrorHandler() SetOpt { + return OptErrorHandler(SilenceErrorHandler()) +} + +// OptPosix informs termtest to treat the command as a posix command +// This will affect line endings as well as output sanitization +func OptPosix(v bool) SetOpt { + return func(o *Opts) error { + o.Posix = v + return nil + } +} + +// OptDefaultTimeout sets the default timeout +func OptDefaultTimeout(duration time.Duration) SetOpt { + return func(o *Opts) error { + o.DefaultTimeout = duration + return nil + } +} + +func OptOutputSanitizer(f cleanerFunc) SetOpt { + return func(o *Opts) error { + o.OutputSanitizer = f + return nil + } +} + +func OptNormalizedLineEnds(v bool) SetOpt { + return func(o *Opts) error { + o.NormalizedLineEnds = v + return nil + } +} + +func (tt *TermTest) SetErrorHandler(handler ErrorHandler) { + tt.opts.ExpectErrorHandler = handler +} + +func (tt *TermTest) SetTest(t *testing.T) { + setTest(tt.opts, t) +} + +func setTest(o *Opts, t *testing.T) { + o.Logger = log.New(&testLogger{t}, "TermTest: ", log.LstdFlags|log.Lshortfile) + o.ExpectErrorHandler = TestErrorHandler(t) +} + +func (tt *TermTest) start() (rerr error) { + expectOpts, err := NewExpectOpts() + defer tt.ExpectErrorHandler(&rerr, expectOpts) + if err != nil { + return fmt.Errorf("could not create expect options: %w", err) + } + + if tt.ptmx != nil { + return fmt.Errorf("already started") + } + + ptmx, err := pty.StartWithSize(tt.cmd, &pty.Winsize{Cols: uint16(tt.opts.Cols), Rows: uint16(tt.opts.Rows)}) + if err != nil { + return fmt.Errorf("could not start pty: %w", err) + } + tt.ptmx = ptmx + + tt.term = vt10x.New(vt10x.WithWriter(ptmx), vt10x.WithSize(tt.opts.Cols, tt.opts.Rows)) + + // Start listening for output + wg := &sync.WaitGroup{} + wg.Add(1) + go func() { + defer tt.opts.Logger.Printf("termtest finished listening") + wg.Done() + err := tt.outputProducer.Listen(tt.ptmx, tt.term) + tt.listenError <- err + }() + wg.Wait() + + return nil +} + +// Wait will wait for the cmd and pty to close and cleans up all the resources allocated by the TermTest +// For most tests you probably want to use ExpectExit* instead. +// Note that unlike ExpectExit*, this will NOT invoke cmd.Wait(). +func (tt *TermTest) Wait(timeout time.Duration) (rerr error) { + tt.opts.Logger.Println("wait called") + defer tt.opts.Logger.Println("wait closed") + + errc := make(chan error, 1) + go func() { + errc <- tt.WaitIndefinitely() + }() + + select { + case err := <-errc: + // WaitIndefinitely already invokes the expect error handler + return err + case <-time.After(timeout): + expectOpts, err := NewExpectOpts() + defer tt.ExpectErrorHandler(&rerr, expectOpts) + if err != nil { + return fmt.Errorf("could not create expect options: %w", err) + } + return fmt.Errorf("timeout after %s while waiting for command and pty to close: %w", timeout, TimeoutError) + } +} + +// Cmd returns the underlying command +func (tt *TermTest) Cmd() *exec.Cmd { + return tt.cmd +} + +// Snapshot returns a string containing a terminal snapshot as a user would see it in a "real" terminal +func (tt *TermTest) Snapshot() string { + return tt.term.String() +} + +// PendingOutput returns any output produced that has not yet been matched against +func (tt *TermTest) PendingOutput() string { + return string(tt.outputProducer.PendingOutput()) +} + +// Output is similar to snapshot, except that it returns all output produced, rather than the current snapshot of output +func (tt *TermTest) Output() string { + return string(tt.outputProducer.Output()) +} + +// Send sends a new line to the terminal, as if a user typed it +func (tt *TermTest) Send(value string) (rerr error) { + expectOpts, err := NewExpectOpts() + defer tt.ExpectErrorHandler(&rerr, expectOpts) + if err != nil { + return fmt.Errorf("could not create expect options: %w", err) + } + + // Todo: Drop this sleep and figure out why without this we seem to be running into a race condition. + // Disabling this sleep will make survey_test.go fail on occasion (rerun it a few times). + time.Sleep(time.Millisecond) + tt.opts.Logger.Printf("Send: %s\n", value) + _, err = tt.ptmx.Write([]byte(value)) + return err +} + +// SendLine sends a new line to the terminal, as if a user typed it, the newline sequence is OS aware +func (tt *TermTest) SendLine(value string) (rerr error) { + lineSep := lineSepPosix + if !tt.opts.Posix { + lineSep = lineSepWindows + } + return tt.Send(fmt.Sprintf("%s%s", value, lineSep)) +} + +// SendCtrlC tries to emulate what would happen in an interactive shell, when the user presses Ctrl-C +// Note: On Windows the Ctrl-C event is only reliable caught when the receiving process is +// listening for os.Interrupt signals. +func (tt *TermTest) SendCtrlC() { + tt.opts.Logger.Printf("SendCtrlC\n") + tt.Send(string([]byte{0x03})) // 0x03 is ASCII character for ^C +} + +func (tt *TermTest) errorHandler(rerr *error) { + err := *rerr + if err == nil { + return + } + + *rerr = tt.opts.ExpectErrorHandler(tt, err) + return +} diff --git a/vendor/github.com/ActiveState/termtest/termtest_other.go b/vendor/github.com/ActiveState/termtest/termtest_other.go new file mode 100644 index 0000000000..79cbc1bcce --- /dev/null +++ b/vendor/github.com/ActiveState/termtest/termtest_other.go @@ -0,0 +1,37 @@ +//go:build !windows +// +build !windows + +package termtest + +import ( + "errors" + "fmt" +) + +func syscallErrorCode(err error) int { + return -1 +} + +func (tt *TermTest) WaitIndefinitely() error { + tt.opts.Logger.Println("WaitIndefinitely called") + defer tt.opts.Logger.Println("WaitIndefinitely closed") + + // Wait for listener to exit + listenError := <-tt.listenError + + // Clean up pty + tt.opts.Logger.Println("Closing pty") + if err := tt.ptmx.Close(); err != nil { + if syscallErrorCode(err) == 0 { + tt.opts.Logger.Println("Ignoring 'The operation completed successfully' error") + } else if errors.Is(err, ERR_ACCESS_DENIED) { + // Ignore access denied error - means process has already finished + tt.opts.Logger.Println("Ignoring access denied error") + } else { + return errors.Join(listenError, fmt.Errorf("failed to close pty: %w", err)) + } + } + tt.opts.Logger.Println("Closed pty") + + return listenError +} diff --git a/vendor/github.com/ActiveState/termtest/termtest_windows.go b/vendor/github.com/ActiveState/termtest/termtest_windows.go new file mode 100644 index 0000000000..b767028a12 --- /dev/null +++ b/vendor/github.com/ActiveState/termtest/termtest_windows.go @@ -0,0 +1,63 @@ +package termtest + +import ( + "errors" + "fmt" + "syscall" + "time" + + gopsutil "github.com/shirou/gopsutil/v3/process" +) + +func syscallErrorCode(err error) int { + if errv, ok := err.(syscall.Errno); ok { + return int(errv) + } + return 0 +} + +// WaitIndefinitely on Windows has to work around a Windows PTY bug where the PTY will NEVER exit by itself: +// https://github.com/photostorm/pty/issues/3 +// Instead we wait for the process itself to exit, and after a grace period will shut down the pty. +func (tt *TermTest) WaitIndefinitely() error { + tt.opts.Logger.Println("WaitIndefinitely called") + defer tt.opts.Logger.Println("WaitIndefinitely closed") + + var procErr error + + tt.opts.Logger.Printf("Waiting for PID %d to exit\n", tt.Cmd().Process.Pid) + for { + // There is a race condition here; which is that the pty could still be processing the last of the output + // when the process exits. This sleep tries to work around this, but on slow hosts this may not be sufficient. + // This also gives some time in between process lookups + time.Sleep(100 * time.Millisecond) + + // For some reason os.Process will always return a process even when the process has exited. + // According to the docs this shouldn't happen, but here we are. + // Using gopsutil seems to correctly identify the (not) running process. + exists, err := gopsutil.PidExists(int32(tt.Cmd().Process.Pid)) + if err != nil { + return fmt.Errorf("could not find process: %d: %w", tt.Cmd().Process.Pid, err) + } + if !exists { + break + } + } + + // Clean up pty + tt.opts.Logger.Println("Closing pty") + if err := tt.ptmx.Close(); err != nil { + if syscallErrorCode(err) == 0 { + tt.opts.Logger.Println("Ignoring 'The operation completed successfully' error") + } else if errors.Is(err, ERR_ACCESS_DENIED) { + // Ignore access denied error - means process has already finished + tt.opts.Logger.Println("Ignoring access denied error") + } else { + return errors.Join(procErr, fmt.Errorf("failed to close pty: %w", err)) + } + } + tt.opts.Logger.Println("Closed pty") + + // Now that the ptmx was closed the listener should also shut down + return errors.Join(procErr, <-tt.listenError) +} diff --git a/vendor/github.com/ActiveState/termtest/testing.go b/vendor/github.com/ActiveState/termtest/testing.go deleted file mode 100644 index dc24fa4f72..0000000000 --- a/vendor/github.com/ActiveState/termtest/testing.go +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2020 ActiveState Software. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file - -package termtest - -import ( - "fmt" - "testing" - - expect "github.com/ActiveState/termtest/expect" - "github.com/ActiveState/termtest/internal/osutils/stacktrace" -) - -// TestSendObserveFn is an example for a SendObserver function, it reports any error during Send calls to the supplied testing instance -func TestSendObserveFn(t *testing.T) func(string, int, error) { - return func(msg string, num int, err error) { - if err == nil { - return - } - - t.Fatalf("Could not send data to terminal\nerror: %v", err) - } -} - -// TestExpectObserveFn an example for a ExpectObserver function, it reports any error occurring durint expect calls to the supplied testing instance -func TestExpectObserveFn(t *testing.T) expect.ExpectObserver { - return func(matchers []expect.Matcher, ms *expect.MatchState, err error) { - if err == nil { - return - } - - var value string - var sep string - for _, matcher := range matchers { - value += fmt.Sprintf("%s%v", sep, matcher.Criteria()) - sep = ", " - } - - t.Fatalf( - "Could not meet expectation: Expectation: '%s'\nError: %v at\n%s\n---\nTerminal snapshot:\n%s\n---\nParsed output:\n%+q\n", - value, err, stacktrace.Get().String(), ms.TermState.StringBeforeCursor(), ms.Buf.String(), - ) - } -} diff --git a/vendor/github.com/ActiveState/termtest/xpty/LICENSE b/vendor/github.com/ActiveState/termtest/xpty/LICENSE deleted file mode 100644 index 0ea09c8e0d..0000000000 --- a/vendor/github.com/ActiveState/termtest/xpty/LICENSE +++ /dev/null @@ -1,29 +0,0 @@ -BSD 3-Clause License - -Copyright (c) 2020, ActiveState Software -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/ActiveState/termtest/xpty/README.md b/vendor/github.com/ActiveState/termtest/xpty/README.md deleted file mode 100644 index 4b9a76da22..0000000000 --- a/vendor/github.com/ActiveState/termtest/xpty/README.md +++ /dev/null @@ -1,32 +0,0 @@ -# termtest/xpty - -Xpty provides an abstraction to run a terminal application in a pseudo-terminal environment for Linux, Mac and Windows. On Windows it uses the [ActiveState/termtest/conpty](https://github.com/ActiveState/termtest/conpty) to run the application inside of a [ConPTY terminal](https://devblogs.microsoft.com/commandline/windows-command-line-introducing-the-windows-pseudo-console-conpty/). The pseudo-terminal is automatically attached to a virtual terminal that is compatible with an `xterm`-terminal. - -## The problem - -Attaching the pseudo-terminal to an `xterm`-compatible virtual terminal is for the following reason: - -If the terminal application sends a cursor position request (CPR) signal, the application usually blocks on read until it receives the response (the column and row number of the cursor) from terminal. `xpty` helps unblocking such programmes, as it actually generates the awaited response. - -## Rune-by-rune streaming - -Reading from the underlying terminal is done with the `ReadRune()` function that returns the next interpretable rune. Such fine-grained and slow output processing allows us to keep the state of the virtual terminal deterministic. - -## Example - -```go -xp, _ := xpty.New(20, 10) -defer xp.Close() - -cmd := exec.Command("/bin/bash") -xp.StartProcessInTerminal(cmd) - -xp.TerminalInPipe().WriteString("echo hello world\n") -xp.TerminalInPipe().WriteString("exit\n") - -buf := new(bytes.Buffer) -n, _ := xp.WriteTo(buf) - -fmt.Printf("Raw output:\n%s\n", buf.String()) -fmt.Printf("Terminal output:\n%s\n", xp.State.String()) -``` diff --git a/vendor/github.com/ActiveState/termtest/xpty/doc.go b/vendor/github.com/ActiveState/termtest/xpty/doc.go deleted file mode 100644 index d68999faa4..0000000000 --- a/vendor/github.com/ActiveState/termtest/xpty/doc.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2020 ActiveState Software. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file - -// Package xpty is an abstraction of a pseudoterminal that is attached to a -// virtual xterm-compatible terminal. -// -// This can be used to automate the execution of terminal applications that rely -// on running inside of a real terminal: Especially if the terminal application -// sends a cursor position request (CPR) signal, it usually blocks on read until -// it receives the response (the column and row number of the cursor) from -// terminal. -// -// The state of the virtual terminal can also be accessed at any point. So, the -// output displayed to a user running the application in a "real" terminal can -// be inspected and analyzed. -package xpty diff --git a/vendor/github.com/ActiveState/termtest/xpty/passthrough_pipe.go b/vendor/github.com/ActiveState/termtest/xpty/passthrough_pipe.go deleted file mode 100644 index 9c62ce486d..0000000000 --- a/vendor/github.com/ActiveState/termtest/xpty/passthrough_pipe.go +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright 2020 ActiveState Software, Inc. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file - -package xpty - -import ( - "bufio" - "context" - "errors" - "fmt" - "io" - "sync/atomic" - "time" - "unicode" -) - -type errPassthroughTimeout struct { - error -} - -func (errPassthroughTimeout) Timeout() bool { return true } - -// PassthroughPipe pipes data from a io.Reader and allows setting a read -// deadline. If a timeout is reached the error is returned, otherwise the error -// from the provided io.Reader returned is passed through instead. -type PassthroughPipe struct { - rdr *bufio.Reader - deadline time.Time - ctx context.Context - cancel context.CancelFunc - lastRead int64 -} - -var maxTime = time.Unix(1<<60-1, 999999999) - -// NewPassthroughPipe returns a new pipe for a io.Reader that passes through -// non-timeout errors. -func NewPassthroughPipe(r *bufio.Reader) *PassthroughPipe { - ctx, cancel := context.WithCancel(context.Background()) - - p := PassthroughPipe{ - rdr: r, - deadline: maxTime, - ctx: ctx, - cancel: cancel, - } - - return &p -} - -// IsBlocked returns true when the PassthroughPipe is (most likely) blocked reading ie., waiting for input -func (p *PassthroughPipe) IsBlocked() bool { - lr := atomic.LoadInt64(&p.lastRead) - return time.Duration(time.Now().UTC().UnixNano()-lr) > 100*time.Millisecond -} - -// SetReadDeadline sets a deadline for a successful read -func (p *PassthroughPipe) SetReadDeadline(d time.Time) { - p.deadline = d -} - -// Close releases all resources allocated by the pipe -func (p *PassthroughPipe) Close() error { - p.cancel() - return nil -} - -type runeResponse struct { - rune rune - size int - err error -} - -// ReadRune reads from the PassthroughPipe and errors out if no data has been written to the pipe before the read deadline expired -// If read is called after the PassthroughPipe has been closed `0, io.EOF` is returned -func (p *PassthroughPipe) ReadRune() (rune, int, error) { - cs := make(chan runeResponse) - done := make(chan struct{}) - defer close(done) - atomic.StoreInt64(&p.lastRead, time.Now().UTC().UnixNano()) - - go func() { - defer close(cs) - - if p.ctx.Err() != nil || p.deadline.Before(time.Now()) { - return - } - - var ( - r rune - sz int - err error - ) - for { - r, sz, err = p.rdr.ReadRune() - - if err != nil && r == unicode.ReplacementChar && sz == 1 { - if p.rdr.Buffered() > 0 { - err = fmt.Errorf("invalid utf8 sequence") - break - } - continue - } - break - } - - select { - case <-done: - return - default: - cs <- runeResponse{r, sz, err} - } - }() - - select { - case c := <-cs: - return c.rune, c.size, c.err - - case <-p.ctx.Done(): - return rune(0), 0, io.EOF - - case <-time.After(p.deadline.Sub(time.Now())): - return rune(0), 0, &errPassthroughTimeout{errors.New("passthrough i/o timeout")} - } -} diff --git a/vendor/github.com/ActiveState/termtest/xpty/xpty.go b/vendor/github.com/ActiveState/termtest/xpty/xpty.go deleted file mode 100644 index 61822d2392..0000000000 --- a/vendor/github.com/ActiveState/termtest/xpty/xpty.go +++ /dev/null @@ -1,234 +0,0 @@ -// Copyright 2020 ActiveState Software. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file - -package xpty - -import ( - "bufio" - "fmt" - "io" - "os" - "os/exec" - "time" - - "github.com/ActiveState/vt10x" -) - -// Xpty reprents an abstract peudo-terminal for the Windows or *nix architecture -type Xpty struct { - *impl // os specific - Term *vt10x.VT - State *vt10x.State - rwPipe *readWritePipe - pp *PassthroughPipe -} - -// readWritePipe is a helper that we use to let the application communicate with a virtual terminal. -type readWritePipe struct { - r *io.PipeReader - w *io.PipeWriter -} - -func newReadWritePipe() *readWritePipe { - r, w := io.Pipe() - return &readWritePipe{r, w} -} - -// Read from the reader part of the pipe -func (rw *readWritePipe) Read(buf []byte) (int, error) { - return rw.r.Read(buf) -} - -// Write to the writer part of the pipe -func (rw *readWritePipe) Write(buf []byte) (int, error) { - return rw.w.Write(buf) -} - -// Close all parts of the pipe -func (rw *readWritePipe) Close() error { - var errMessage string - e := rw.r.Close() - if e != nil { - errMessage += fmt.Sprintf("failed to close read-part of pipe: %v ", e) - } - e = rw.w.Close() - if e != nil { - errMessage += fmt.Sprintf("failed to close write-part of pipe: %v ", e) - } - if len(errMessage) > 0 { - return fmt.Errorf(errMessage) - } - return nil -} - -func (p *Xpty) openVT(cols uint16, rows uint16) (err error) { - - /* - We are creating a communication pipe to handle DSR (device status report) and - (CPR) cursor position report queries. - - If an application is sending these queries it is usually expecting a response - from the terminal emulator (like xterm). If the response is not send, the - application may hang forever waiting for it. The vt10x terminal emulator is able to handle it. If - we multiplex the ptm output to a vt10x terminal, the DSR/CPR requests are - intercepted and it can inject the responses in the read-write-pipe. - - The read-part of the read-write-pipe continuously feeds into the ptm device that - forwards it to the application. - - DSR/CPR req reply - app -------------> pts/ptm -> vt10x.VT ------> rwPipe --> ptm/pts --> app - - Note: This is a simplification from github.com/hinshun/vt10x (console.go) - */ - - p.rwPipe = newReadWritePipe() - - // Note: the Term instance also closes the rwPipe - p.Term, err = vt10x.Create(p.State, p.rwPipe) - if err != nil { - return err - } - p.Term.Resize(int(cols), int(rows)) - - // connect the pipes as described above - go func() { - // this drains the rwPipe continuously. If that didn't happen, we would block on write. - io.Copy(p.impl.terminalInPipe(), p.rwPipe) - }() - - // forward the terminal output to a passthrough pipe, such that we can read it rune-by-rune - // and can control read timeouts - br := bufio.NewReaderSize(p.impl.terminalOutPipe(), 100) - p.pp = NewPassthroughPipe(br) - return nil -} - -// Resize resizes the underlying pseudo-terminal -func (p *Xpty) Resize(cols, rows uint16) error { - p.Term.Resize(int(cols), int(rows)) - return p.impl.resize(cols, rows) -} - -// New opens a pseudo-terminal of the given size -func New(cols uint16, rows uint16, recordHistory bool) (*Xpty, error) { - xpImpl, err := open(cols, rows) - if err != nil { - return nil, err - } - xp := &Xpty{impl: xpImpl, Term: nil, State: &vt10x.State{RecordHistory: recordHistory}} - err = xp.openVT(cols, rows) - if err != nil { - return nil, err - } - - return xp, nil -} - -// ReadRune reads a single rune from the terminal output pipe, and updates the terminal -func (p *Xpty) ReadRune() (rune, int, error) { - c, sz, err := p.pp.ReadRune() - if err != nil { - return c, 0, err - } - // update the terminal - p.Term.WriteRune(c) - return c, sz, err -} - -// SetReadDeadline sets a deadline for a successful read the next rune -func (p *Xpty) SetReadDeadline(d time.Time) { - p.pp.SetReadDeadline(d) -} - -// TerminalInPipe returns a writer that can be used to write user input to the pseudo terminal. -// On unix this is the /dev/ptm file -func (p *Xpty) TerminalInPipe() io.Writer { - return p.impl.terminalInPipe() -} - -// WriteTo writes the terminal output stream to a writer w -func (p *Xpty) WriteTo(w io.Writer) (int64, error) { - var written int64 - for { - c, sz, err := p.ReadRune() - if err != nil { - return written, err - } - written += int64(sz) - _, err = w.Write([]byte(string(c))) - if err != nil { - return written, fmt.Errorf("failed writing to writer: %w", err) - } - } - -} - -// WaitTillDrained waits until the PassthroughPipe is blocked in the reading state. -// When this function returns, the PassthroughPipe should be blocked in the -// reading state waiting for more input. -func (p *Xpty) WaitTillDrained() { - for { - if p.pp.IsBlocked() { - return - } - time.Sleep(100 * time.Millisecond) - } -} - -// CloseTTY closes just the terminal, giving you some time to finish reading from the -// pass-through pipe later. -// Call CloseReaders() when you are done reading all the data that is still buffered -// Consider this little dance to avoid losing any data: -// go func() { -// ... -// // command finishes -// cmd.Wait() -// // wait until the pass-through pipe has consumed all data -// xp.WaitTillDrained() -// xp.CloseTTY() -// }() -// xp.WriteTo(...) -// // now close the passthrough pipe -// xp.CloseReaders() -func (p *Xpty) CloseTTY() error { - return p.impl.close() -} - -// CloseReaders closes the passthrough pipe -func (p *Xpty) CloseReaders() error { - err := p.pp.Close() - if err != nil { - return err - } - if p.Term == nil { - return nil - } - return p.Term.Close() -} - -// Close closes the abstracted pseudo-terminal -func (p *Xpty) Close() error { - err := p.CloseTTY() - if err != nil { - return err - } - return p.CloseReaders() -} - -// Tty returns the pseudo terminal files that an application can read from or write to -// This is only available on linux, and would return the "slave" /dev/pts file -func (p *Xpty) Tty() *os.File { - return p.impl.tty() -} - -// TerminalOutFd returns the file descriptor of the terminal -func (p *Xpty) TerminalOutFd() uintptr { - return p.impl.terminalOutFd() -} - -// StartProcessInTerminal executes the given command connected to the abstracted pseudo-terminal -func (p *Xpty) StartProcessInTerminal(cmd *exec.Cmd) error { - return p.impl.startProcessInTerminal(cmd) -} diff --git a/vendor/github.com/ActiveState/termtest/xpty/xpty_other.go b/vendor/github.com/ActiveState/termtest/xpty/xpty_other.go deleted file mode 100644 index dda18ad4a0..0000000000 --- a/vendor/github.com/ActiveState/termtest/xpty/xpty_other.go +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2020 ActiveState Software. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file - -// +build darwin dragonfly linux netbsd openbsd solaris - -package xpty - -import ( - "io" - "os" - "os/exec" - "syscall" - - "github.com/creack/pty" -) - -type impl struct { - ptm *os.File - pts *os.File - rwPipe *readWritePipe -} - -func open(cols uint16, rows uint16) (*impl, error) { - ptm, pts, err := pty.Open() - if err != nil { - return nil, err - } - err = pty.Setsize(ptm, &pty.Winsize{Cols: cols, Rows: rows}) - if err != nil { - return nil, err - } - return &impl{ptm: ptm, pts: pts}, nil -} - -func (p *impl) terminalOutPipe() io.Reader { - return p.ptm -} - -func (p *impl) terminalInPipe() io.Writer { - return p.ptm -} - -func (p *impl) resize(cols uint16, rows uint16) error { - return pty.Setsize(p.ptm, &pty.Winsize{Cols: cols, Rows: rows}) -} - -func (p *impl) close() error { - p.pts.Close() - p.ptm.Close() - return nil -} - -func (p *impl) tty() *os.File { - return p.pts -} - -func (p *impl) terminalOutFd() uintptr { - return p.ptm.Fd() -} - -func (p *impl) startProcessInTerminal(cmd *exec.Cmd) error { - cmd.Stdin = p.pts - cmd.Stdout = p.pts - cmd.Stderr = p.pts - if cmd.SysProcAttr == nil { - cmd.SysProcAttr = &syscall.SysProcAttr{} - } - cmd.SysProcAttr.Setctty = true - cmd.SysProcAttr.Setsid = true - return cmd.Start() -} diff --git a/vendor/github.com/ActiveState/termtest/xpty/xpty_windows.go b/vendor/github.com/ActiveState/termtest/xpty/xpty_windows.go deleted file mode 100644 index b83ed52db5..0000000000 --- a/vendor/github.com/ActiveState/termtest/xpty/xpty_windows.go +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2020 ActiveState Software. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file - -// +build windows - -package xpty - -import ( - "fmt" - "io" - "os" - "os/exec" - "syscall" - - conpty "github.com/ActiveState/termtest/conpty" -) - -type impl struct { - *conpty.ConPty -} - -func open(cols, rows uint16) (*impl, error) { - c, err := conpty.New(int16(cols), int16(rows)) - if err != nil { - return nil, err - } - return &impl{c}, nil -} - -func (p *impl) terminalOutPipe() io.Reader { - return p.OutPipe() -} - -func (p *impl) terminalInPipe() io.Writer { - return p.InPipe() -} - -func (p *impl) close() error { - return p.Close() -} - -func (p *impl) tty() *os.File { - return nil -} - -func (p *impl) terminalOutFd() uintptr { - return p.OutFd() -} - -func (p *impl) resize(cols, rows uint16) error { - return p.ConPty.Resize(cols, rows) -} - -func (p *impl) startProcessInTerminal(c *exec.Cmd) (err error) { - var argv []string - if len(c.Args) > 0 { - argv = c.Args - } else { - argv = []string{c.Path} - } - - var envv []string - if c.Env != nil { - envv = c.Env - } else { - envv = os.Environ() - } - pid, _, err := p.Spawn(c.Path, argv, &syscall.ProcAttr{ - Dir: c.Dir, - Env: envv, - }) - if err != nil { - return fmt.Errorf("Failed to spawn process in terminal: %w", err) - } - - // Let's pray that this always works. Unfortunately we cannot create our process from a process handle. - c.Process, err = os.FindProcess(pid) - if err != nil { - return fmt.Errorf("Failed to create an os.Process struct: %w", err) - } - - // runtime.SetFinalizer(h, ) - - return nil -} diff --git a/vendor/github.com/ActiveState/vt10x/expect.go b/vendor/github.com/ActiveState/vt10x/expect.go deleted file mode 100644 index 7ae52f321e..0000000000 --- a/vendor/github.com/ActiveState/vt10x/expect.go +++ /dev/null @@ -1,31 +0,0 @@ -// +build !windows - -package vt10x - -import ( - expect "github.com/Netflix/go-expect" - "github.com/kr/pty" -) - -// NewVT10XConsole returns a new expect.Console that multiplexes the -// Stdin/Stdout to a VT10X terminal, allowing Console to interact with an -// application sending ANSI escape sequences. -func NewVT10XConsole(opts ...expect.ConsoleOpt) (*expect.Console, *State, error) { - ptm, pts, err := pty.Open() - if err != nil { - return nil, nil, err - } - - var state State - term, err := Create(&state, pts) - if err != nil { - return nil, nil, err - } - - c, err := expect.NewConsole(append(opts, expect.WithStdin(ptm), expect.WithStdout(term), expect.WithCloser(pts, ptm, term))...) - if err != nil { - return nil, nil, err - } - - return c, &state, nil -} diff --git a/vendor/github.com/ActiveState/vt10x/str.go b/vendor/github.com/ActiveState/vt10x/str.go deleted file mode 100644 index c8ca50cbcb..0000000000 --- a/vendor/github.com/ActiveState/vt10x/str.go +++ /dev/null @@ -1,94 +0,0 @@ -package vt10x - -import ( - "strconv" - "strings" -) - -// STR sequences are similar to CSI sequences, but have string arguments (and -// as far as I can tell, don't really have a name; STR is the name I took from -// suckless which I imagine comes from rxvt or xterm). -type strEscape struct { - typ rune - buf []rune - args []string -} - -func (s *strEscape) reset() { - s.typ = 0 - s.buf = s.buf[:0] - s.args = nil -} - -func (s *strEscape) put(c rune) { - // TODO: improve allocs with an array backed slice; bench first - if len(s.buf) < 256 { - s.buf = append(s.buf, c) - } - // Going by st, it is better to remain silent when the STR sequence is not - // ended so that it is apparent to users something is wrong. The length sanity - // check ensures we don't absorb the entire stream into memory. - // TODO: see what rxvt or xterm does -} - -func (s *strEscape) parse() { - s.args = strings.Split(string(s.buf), ";") -} - -func (s *strEscape) arg(i, def int) int { - if i >= len(s.args) || i < 0 { - return def - } - i, err := strconv.Atoi(s.args[i]) - if err != nil { - return def - } - return i -} - -func (s *strEscape) argString(i int, def string) string { - if i >= len(s.args) || i < 0 { - return def - } - return s.args[i] -} - -func (t *State) handleSTR() { - s := &t.str - s.parse() - - switch s.typ { - case ']': // OSC - operating system command - switch d := s.arg(0, 0); d { - case 0, 1, 2: - title := s.argString(1, "") - if title != "" { - t.setTitle(title) - } - case 4: // color set - if len(s.args) < 3 { - break - } - // setcolorname(s.arg(1, 0), s.argString(2, "")) - case 104: // color reset - // TODO: complain about invalid color, redraw, etc. - // setcolorname(s.arg(1, 0), nil) - default: - t.logf("unknown OSC command %d\n", d) - // TODO: s.dump() - } - case 'k': // old title set compatibility - title := s.argString(0, "") - if title != "" { - t.setTitle(title) - } - default: - // TODO: Ignore these codes instead of complain? - // 'P': // DSC - device control string - // '_': // APC - application program command - // '^': // PM - privacy message - - t.logf("unhandled STR sequence '%c'\n", s.typ) - // t.str.dump() - } -} diff --git a/vendor/github.com/ActiveState/vt10x/strip.go b/vendor/github.com/ActiveState/vt10x/strip.go deleted file mode 100644 index 232f90dc24..0000000000 --- a/vendor/github.com/ActiveState/vt10x/strip.go +++ /dev/null @@ -1,55 +0,0 @@ -package vt10x - -import ( - "unicode" - "unicode/utf8" -) - -type VTStrip struct { - VT -} - -func NewStrip() *VTStrip { - t := &VTStrip{ - VT{ - dest: &State{}, - rwc: nil, - }, - } - t.init() - return t -} - -// Strip returns in with all VT10x escape sequences stripped. An error is -// also returned if one or more of the stripped escape sequences are invalid. -func (t *VTStrip) Strip(in []byte) ([]byte, error) { - var locked bool - defer func() { - if locked { - t.dest.unlock() - } - }() - out := make([]byte, len(in)) - nout := 0 - s := string(in) - for i, w := 0, 0; i < len(s); i += w { - c, sz := utf8.DecodeRuneInString(s[i:]) - w = sz - if c == unicode.ReplacementChar && sz == 1 { - t.dest.logln("invalid utf8 sequence") - break - } - if !locked { - t.dest.lock() - locked = true - } - - // put rune for parsing and update state - isPrintable := t.dest.put(c) - if isPrintable { - copy(out[nout:nout+w], in[i:i+w]) - nout += w - } - } - return out[:nout], nil -} diff --git a/vendor/github.com/ActiveState/vt10x/vt.go b/vendor/github.com/ActiveState/vt10x/vt.go deleted file mode 100644 index 954a51a3f6..0000000000 --- a/vendor/github.com/ActiveState/vt10x/vt.go +++ /dev/null @@ -1,152 +0,0 @@ -package vt10x - -import ( - "bufio" - "bytes" - "io" - "unicode" - "unicode/utf8" -) - -// VT represents the virtual terminal emulator. -type VT struct { - dest *State - in io.Reader - out io.Writer - rwc io.ReadWriteCloser - br *bufio.Reader -} - -// Create initializes a virtual terminal emulator with the target state -// and io.ReadWriteCloser input. -func Create(state *State, rwc io.ReadWriteCloser) (*VT, error) { - t := &VT{ - dest: state, - rwc: rwc, - } - t.init() - return t, nil -} - -func New(state *State, in io.Reader, out io.Writer) (*VT, error) { - t := &VT{ - dest: state, - in: in, - out: out, - } - t.init() - return t, nil -} - -func (t *VT) init() { - if t.rwc != nil { - t.br = bufio.NewReader(t.rwc) - t.dest.w = t.rwc - } else { - t.br = bufio.NewReader(t.in) - t.dest.w = t.out - } - t.dest.numlock = true - t.dest.state = t.dest.parse - t.dest.cur.attr.fg = DefaultFG - t.dest.cur.attr.bg = DefaultBG - t.Resize(80, 24) - t.dest.reset() -} - -// WriteRune writes a single rune to the terminal -func (t *VT) WriteRune(r rune) { - t.dest.lock() - defer t.dest.unlock() - t.dest.put(r) -} - -// Write parses input and writes terminal changes to state. -func (t *VT) Write(p []byte) (int, error) { - var written int - r := bytes.NewReader(p) - t.dest.lock() - defer t.dest.unlock() - for { - c, sz, err := r.ReadRune() - if err != nil { - if err == io.EOF { - break - } - return written, err - } - written += sz - if c == unicode.ReplacementChar && sz == 1 { - if r.Len() == 0 { - // not enough bytes for a full rune - return written - 1, nil - } - t.dest.logln("invalid utf8 sequence") - continue - } - t.dest.put(c) - } - return written, nil -} - -// Close closes the io.ReadWriteCloser. -func (t *VT) Close() error { - if t.rwc == nil { - return nil - } - return t.rwc.Close() -} - -// Parse blocks on read on pty or io.ReadCloser, then parses sequences until -// buffer empties. State is locked as soon as first rune is read, and unlocked -// when buffer is empty. -// TODO: add tests for expected blocking behavior -func (t *VT) Parse() error { - var locked bool - defer func() { - if locked { - t.dest.unlock() - } - }() - for { - c, sz, err := t.br.ReadRune() - if err != nil { - return err - } - if c == unicode.ReplacementChar && sz == 1 { - t.dest.logln("invalid utf8 sequence") - break - } - if !locked { - t.dest.lock() - locked = true - } - - // put rune for parsing and update state - t.dest.put(c) - - // break if our buffer is empty, or if buffer contains an - // incomplete rune. - n := t.br.Buffered() - if n == 0 || (n < 4 && !fullRuneBuffered(t.br)) { - break - } - } - return nil -} - -func fullRuneBuffered(br *bufio.Reader) bool { - n := br.Buffered() - buf, err := br.Peek(n) - if err != nil { - return false - } - return utf8.FullRune(buf) -} - -// Resize reports new size to pty and updates state. -func (t *VT) Resize(cols, rows int) { - t.dest.lock() - defer t.dest.unlock() - _ = t.dest.resize(cols, rows) -} diff --git a/vendor/github.com/Netflix/go-expect/.travis.yml b/vendor/github.com/Netflix/go-expect/.travis.yml deleted file mode 100644 index 5d6c8fefd2..0000000000 --- a/vendor/github.com/Netflix/go-expect/.travis.yml +++ /dev/null @@ -1,10 +0,0 @@ -language: go - -os: - - linux - - osx - -go: - - "1.13.15" - - "1.14.10" - - master diff --git a/vendor/github.com/Netflix/go-expect/LICENSE b/vendor/github.com/Netflix/go-expect/LICENSE deleted file mode 100644 index af349b6ded..0000000000 --- a/vendor/github.com/Netflix/go-expect/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2018 Netflix, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/Netflix/go-expect/OSSMETADATA b/vendor/github.com/Netflix/go-expect/OSSMETADATA deleted file mode 100644 index b96d4a4dfa..0000000000 --- a/vendor/github.com/Netflix/go-expect/OSSMETADATA +++ /dev/null @@ -1 +0,0 @@ -osslifecycle=active diff --git a/vendor/github.com/Netflix/go-expect/README.md b/vendor/github.com/Netflix/go-expect/README.md deleted file mode 100644 index dc01b5691a..0000000000 --- a/vendor/github.com/Netflix/go-expect/README.md +++ /dev/null @@ -1,98 +0,0 @@ -# go-expect - -![Go](https://github.com/Netflix/go-expect/workflows/Go/badge.svg) -[![codecov](https://codecov.io/gh/Netflix/go-expect/branch/master/graph/badge.svg?token=rZtccXvdCw)](https://codecov.io/gh/Netflix/go-expect) -[![Build Status](https://travis-ci.com/Netflix/go-expect.svg?branch=master)](https://travis-ci.com/Netflix/go-expect) -[![GoDoc](https://godoc.org/github.com/Netflix/go-expect?status.svg)](https://godoc.org/github.com/Netflix/go-expect) -[![NetflixOSS Lifecycle](https://img.shields.io/osslifecycle/Netflix/go-expect.svg)]() - -Package expect provides an expect-like interface to automate control of applications. It is unlike expect in that it does not spawn or manage process lifecycle. This package only focuses on expecting output and sending input through it's pseudoterminal. - -## Usage - -### `os.Exec` example - -```go -package main - -import ( - "log" - "os" - "os/exec" - "time" - - expect "github.com/Netflix/go-expect" -) - -func main() { - c, err := expect.NewConsole(expect.WithStdout(os.Stdout)) - if err != nil { - log.Fatal(err) - } - defer c.Close() - - cmd := exec.Command("vi") - cmd.Stdin = c.Tty() - cmd.Stdout = c.Tty() - cmd.Stderr = c.Tty() - - go func() { - c.ExpectEOF() - }() - - err = cmd.Start() - if err != nil { - log.Fatal(err) - } - - time.Sleep(time.Second) - c.Send("iHello world\x1b") - time.Sleep(time.Second) - c.Send("dd") - time.Sleep(time.Second) - c.SendLine(":q!") - - err = cmd.Wait() - if err != nil { - log.Fatal(err) - } -} -``` - -### `golang.org/x/crypto/ssh/terminal` example - -``` -package main - -import ( - "fmt" - - "golang.org/x/crypto/ssh/terminal" - - expect "github.com/Netflix/go-expect" -) - -func getPassword(fd int) string { - bytePassword, _ := terminal.ReadPassword(fd) - - return string(bytePassword) -} - -func main() { - c, _ := expect.NewConsole() - - defer c.Close() - - donec := make(chan struct{}) - go func() { - defer close(donec) - c.SendLine("hunter2") - }() - - echoText := getPassword(int(c.Tty().Fd())) - - <-donec - - fmt.Printf("\nPassword from stdin: %s", echoText) -} -``` diff --git a/vendor/github.com/Netflix/go-expect/console.go b/vendor/github.com/Netflix/go-expect/console.go deleted file mode 100644 index 35c97dcdb9..0000000000 --- a/vendor/github.com/Netflix/go-expect/console.go +++ /dev/null @@ -1,241 +0,0 @@ -// Copyright 2018 Netflix, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package expect - -import ( - "bufio" - "fmt" - "io" - "io/ioutil" - "log" - "os" - "time" - "unicode/utf8" - - "github.com/kr/pty" -) - -// Console is an interface to automate input and output for interactive -// applications. Console can block until a specified output is received and send -// input back on it's tty. Console can also multiplex other sources of input -// and multiplex its output to other writers. -type Console struct { - opts ConsoleOpts - ptm *os.File - pts *os.File - passthroughPipe *PassthroughPipe - runeReader *bufio.Reader - closers []io.Closer -} - -// ConsoleOpt allows setting Console options. -type ConsoleOpt func(*ConsoleOpts) error - -// ConsoleOpts provides additional options on creating a Console. -type ConsoleOpts struct { - Logger *log.Logger - Stdins []io.Reader - Stdouts []io.Writer - Closers []io.Closer - ExpectObservers []ExpectObserver - SendObservers []SendObserver - ReadTimeout *time.Duration -} - -// ExpectObserver provides an interface for a function callback that will -// be called after each Expect operation. -// matchers will be the list of active matchers when an error occurred, -// or a list of matchers that matched `buf` when err is nil. -// buf is the captured output that was matched against. -// err is error that might have occurred. May be nil. -type ExpectObserver func(matchers []Matcher, buf string, err error) - -// SendObserver provides an interface for a function callback that will -// be called after each Send operation. -// msg is the string that was sent. -// num is the number of bytes actually sent. -// err is the error that might have occured. May be nil. -type SendObserver func(msg string, num int, err error) - -// WithStdout adds writers that Console duplicates writes to, similar to the -// Unix tee(1) command. -// -// Each write is written to each listed writer, one at a time. Console is the -// last writer, writing to it's internal buffer for matching expects. -// If a listed writer returns an error, that overall write operation stops and -// returns the error; it does not continue down the list. -func WithStdout(writers ...io.Writer) ConsoleOpt { - return func(opts *ConsoleOpts) error { - opts.Stdouts = append(opts.Stdouts, writers...) - return nil - } -} - -// WithStdin adds readers that bytes read are written to Console's tty. If a -// listed reader returns an error, that reader will not be continued to read. -func WithStdin(readers ...io.Reader) ConsoleOpt { - return func(opts *ConsoleOpts) error { - opts.Stdins = append(opts.Stdins, readers...) - return nil - } -} - -// WithCloser adds closers that are closed in order when Console is closed. -func WithCloser(closer ...io.Closer) ConsoleOpt { - return func(opts *ConsoleOpts) error { - opts.Closers = append(opts.Closers, closer...) - return nil - } -} - -// WithLogger adds a logger for Console to log debugging information to. By -// default Console will discard logs. -func WithLogger(logger *log.Logger) ConsoleOpt { - return func(opts *ConsoleOpts) error { - opts.Logger = logger - return nil - } -} - -// WithExpectObserver adds an ExpectObserver to allow monitoring Expect operations. -func WithExpectObserver(observers ...ExpectObserver) ConsoleOpt { - return func(opts *ConsoleOpts) error { - opts.ExpectObservers = append(opts.ExpectObservers, observers...) - return nil - } -} - -// WithSendObserver adds a SendObserver to allow monitoring Send operations. -func WithSendObserver(observers ...SendObserver) ConsoleOpt { - return func(opts *ConsoleOpts) error { - opts.SendObservers = append(opts.SendObservers, observers...) - return nil - } -} - -// WithDefaultTimeout sets a default read timeout during Expect statements. -func WithDefaultTimeout(timeout time.Duration) ConsoleOpt { - return func(opts *ConsoleOpts) error { - opts.ReadTimeout = &timeout - return nil - } -} - -// NewConsole returns a new Console with the given options. -func NewConsole(opts ...ConsoleOpt) (*Console, error) { - options := ConsoleOpts{ - Logger: log.New(ioutil.Discard, "", 0), - } - - for _, opt := range opts { - if err := opt(&options); err != nil { - return nil, err - } - } - - ptm, pts, err := pty.Open() - if err != nil { - return nil, err - } - closers := append(options.Closers, pts, ptm) - - passthroughPipe, err := NewPassthroughPipe(ptm) - if err != nil { - return nil, err - } - closers = append(options.Closers, passthroughPipe) - - c := &Console{ - opts: options, - ptm: ptm, - pts: pts, - passthroughPipe: passthroughPipe, - runeReader: bufio.NewReaderSize(passthroughPipe, utf8.UTFMax), - closers: closers, - } - - for _, stdin := range options.Stdins { - go func(stdin io.Reader) { - _, err := io.Copy(c, stdin) - if err != nil { - c.Logf("failed to copy stdin: %s", err) - } - }(stdin) - } - - return c, nil -} - -// Tty returns Console's pts (slave part of a pty). A pseudoterminal, or pty is -// a pair of psuedo-devices, one of which, the slave, emulates a real text -// terminal device. -func (c *Console) Tty() *os.File { - return c.pts -} - -// Read reads bytes b from Console's tty. -func (c *Console) Read(b []byte) (int, error) { - return c.ptm.Read(b) -} - -// Write writes bytes b to Console's tty. -func (c *Console) Write(b []byte) (int, error) { - c.Logf("console write: %q", b) - return c.ptm.Write(b) -} - -// Fd returns Console's file descripting referencing the master part of its -// pty. -func (c *Console) Fd() uintptr { - return c.ptm.Fd() -} - -// Close closes Console's tty. Calling Close will unblock Expect and ExpectEOF. -func (c *Console) Close() error { - for _, fd := range c.closers { - err := fd.Close() - if err != nil { - c.Logf("failed to close: %s", err) - } - } - return nil -} - -// Send writes string s to Console's tty. -func (c *Console) Send(s string) (int, error) { - c.Logf("console send: %q", s) - n, err := c.ptm.WriteString(s) - for _, observer := range c.opts.SendObservers { - observer(s, n, err) - } - return n, err -} - -// SendLine writes string s to Console's tty with a trailing newline. -func (c *Console) SendLine(s string) (int, error) { - return c.Send(fmt.Sprintf("%s\n", s)) -} - -// Log prints to Console's logger. -// Arguments are handled in the manner of fmt.Print. -func (c *Console) Log(v ...interface{}) { - c.opts.Logger.Print(v...) -} - -// Logf prints to Console's logger. -// Arguments are handled in the manner of fmt.Printf. -func (c *Console) Logf(format string, v ...interface{}) { - c.opts.Logger.Printf(format, v...) -} diff --git a/vendor/github.com/Netflix/go-expect/doc.go b/vendor/github.com/Netflix/go-expect/doc.go deleted file mode 100644 index a0163f0e50..0000000000 --- a/vendor/github.com/Netflix/go-expect/doc.go +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2018 Netflix, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package expect provides an expect-like interface to automate control of -// applications. It is unlike expect in that it does not spawn or manage -// process lifecycle. This package only focuses on expecting output and sending -// input through it's psuedoterminal. -package expect diff --git a/vendor/github.com/Netflix/go-expect/expect.go b/vendor/github.com/Netflix/go-expect/expect.go deleted file mode 100644 index b99b326de4..0000000000 --- a/vendor/github.com/Netflix/go-expect/expect.go +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright 2018 Netflix, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package expect - -import ( - "bufio" - "bytes" - "fmt" - "io" - "time" - "unicode/utf8" -) - -// Expectf reads from the Console's tty until the provided formatted string -// is read or an error occurs, and returns the buffer read by Console. -func (c *Console) Expectf(format string, args ...interface{}) (string, error) { - return c.Expect(String(fmt.Sprintf(format, args...))) -} - -// ExpectString reads from Console's tty until the provided string is read or -// an error occurs, and returns the buffer read by Console. -func (c *Console) ExpectString(s string) (string, error) { - return c.Expect(String(s)) -} - -// ExpectEOF reads from Console's tty until EOF or an error occurs, and returns -// the buffer read by Console. We also treat the PTSClosed error as an EOF. -func (c *Console) ExpectEOF() (string, error) { - return c.Expect(EOF, PTSClosed) -} - -// Expect reads from Console's tty until a condition specified from opts is -// encountered or an error occurs, and returns the buffer read by console. -// No extra bytes are read once a condition is met, so if a program isn't -// expecting input yet, it will be blocked. Sends are queued up in tty's -// internal buffer so that the next Expect will read the remaining bytes (i.e. -// rest of prompt) as well as its conditions. -func (c *Console) Expect(opts ...ExpectOpt) (string, error) { - var options ExpectOpts - for _, opt := range opts { - if err := opt(&options); err != nil { - return "", err - } - } - - buf := new(bytes.Buffer) - writer := io.MultiWriter(append(c.opts.Stdouts, buf)...) - runeWriter := bufio.NewWriterSize(writer, utf8.UTFMax) - - readTimeout := c.opts.ReadTimeout - if options.ReadTimeout != nil { - readTimeout = options.ReadTimeout - } - - var matcher Matcher - var err error - - defer func() { - for _, observer := range c.opts.ExpectObservers { - if matcher != nil { - observer([]Matcher{matcher}, buf.String(), err) - return - } - observer(options.Matchers, buf.String(), err) - } - }() - - for { - if readTimeout != nil { - err = c.passthroughPipe.SetReadDeadline(time.Now().Add(*readTimeout)) - if err != nil { - return buf.String(), err - } - } - - var r rune - r, _, err = c.runeReader.ReadRune() - if err != nil { - matcher = options.Match(err) - if matcher != nil { - err = nil - break - } - return buf.String(), err - } - - c.Logf("expect read: %q", string(r)) - _, err = runeWriter.WriteRune(r) - if err != nil { - return buf.String(), err - } - - // Immediately flush rune to the underlying writers. - err = runeWriter.Flush() - if err != nil { - return buf.String(), err - } - - matcher = options.Match(buf) - if matcher != nil { - break - } - } - - if matcher != nil { - cb, ok := matcher.(CallbackMatcher) - if ok { - err = cb.Callback(buf) - if err != nil { - return buf.String(), err - } - } - } - - return buf.String(), err -} diff --git a/vendor/github.com/Netflix/go-expect/expect_opt.go b/vendor/github.com/Netflix/go-expect/expect_opt.go deleted file mode 100644 index fb37dd0b68..0000000000 --- a/vendor/github.com/Netflix/go-expect/expect_opt.go +++ /dev/null @@ -1,318 +0,0 @@ -// Copyright 2018 Netflix, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package expect - -import ( - "bytes" - "io" - "os" - "regexp" - "strings" - "syscall" - "time" -) - -// ExpectOpt allows settings Expect options. -type ExpectOpt func(*ExpectOpts) error - -// WithTimeout sets a read timeout for an Expect statement. -func WithTimeout(timeout time.Duration) ExpectOpt { - return func(opts *ExpectOpts) error { - opts.ReadTimeout = &timeout - return nil - } -} - -// ConsoleCallback is a callback function to execute if a match is found for -// the chained matcher. -type ConsoleCallback func(buf *bytes.Buffer) error - -// Then returns an Expect condition to execute a callback if a match is found -// for the chained matcher. -func (eo ExpectOpt) Then(f ConsoleCallback) ExpectOpt { - return func(opts *ExpectOpts) error { - var options ExpectOpts - err := eo(&options) - if err != nil { - return err - } - - for _, matcher := range options.Matchers { - opts.Matchers = append(opts.Matchers, &callbackMatcher{ - f: f, - matcher: matcher, - }) - } - return nil - } -} - -// ExpectOpts provides additional options on Expect. -type ExpectOpts struct { - Matchers []Matcher - ReadTimeout *time.Duration -} - -// Match sequentially calls Match on all matchers in ExpectOpts and returns the -// first matcher if a match exists, otherwise nil. -func (eo ExpectOpts) Match(v interface{}) Matcher { - for _, matcher := range eo.Matchers { - if matcher.Match(v) { - return matcher - } - } - return nil -} - -// CallbackMatcher is a matcher that provides a Callback function. -type CallbackMatcher interface { - // Callback executes the matcher's callback with the content buffer at the - // time of match. - Callback(buf *bytes.Buffer) error -} - -// Matcher provides an interface for finding a match in content read from -// Console's tty. -type Matcher interface { - // Match returns true iff a match is found. - Match(v interface{}) bool - Criteria() interface{} -} - -// callbackMatcher fulfills the Matcher and CallbackMatcher interface to match -// using its embedded matcher and provide a callback function. -type callbackMatcher struct { - f ConsoleCallback - matcher Matcher -} - -func (cm *callbackMatcher) Match(v interface{}) bool { - return cm.matcher.Match(v) -} - -func (cm *callbackMatcher) Criteria() interface{} { - return cm.matcher.Criteria() -} - -func (cm *callbackMatcher) Callback(buf *bytes.Buffer) error { - cb, ok := cm.matcher.(CallbackMatcher) - if ok { - err := cb.Callback(buf) - if err != nil { - return err - } - } - err := cm.f(buf) - if err != nil { - return err - } - return nil -} - -// errorMatcher fulfills the Matcher interface to match a specific error. -type errorMatcher struct { - err error -} - -func (em *errorMatcher) Match(v interface{}) bool { - err, ok := v.(error) - if !ok { - return false - } - return err == em.err -} - -func (em *errorMatcher) Criteria() interface{} { - return em.err -} - -// pathErrorMatcher fulfills the Matcher interface to match a specific os.PathError. -type pathErrorMatcher struct { - pathError os.PathError -} - -func (em *pathErrorMatcher) Match(v interface{}) bool { - pathError, ok := v.(*os.PathError) - if !ok { - return false - } - return *pathError == em.pathError -} - -func (em *pathErrorMatcher) Criteria() interface{} { - return em.pathError -} - -// stringMatcher fulfills the Matcher interface to match strings against a given -// bytes.Buffer. -type stringMatcher struct { - str string -} - -func (sm *stringMatcher) Match(v interface{}) bool { - buf, ok := v.(*bytes.Buffer) - if !ok { - return false - } - if strings.Contains(buf.String(), sm.str) { - return true - } - return false -} - -func (sm *stringMatcher) Criteria() interface{} { - return sm.str -} - -// regexpMatcher fulfills the Matcher interface to match Regexp against a given -// bytes.Buffer. -type regexpMatcher struct { - re *regexp.Regexp -} - -func (rm *regexpMatcher) Match(v interface{}) bool { - buf, ok := v.(*bytes.Buffer) - if !ok { - return false - } - return rm.re.Match(buf.Bytes()) -} - -func (rm *regexpMatcher) Criteria() interface{} { - return rm.re -} - -// allMatcher fulfills the Matcher interface to match a group of ExpectOpt -// against any value. -type allMatcher struct { - options ExpectOpts -} - -func (am *allMatcher) Match(v interface{}) bool { - var matchers []Matcher - for _, matcher := range am.options.Matchers { - if matcher.Match(v) { - continue - } - matchers = append(matchers, matcher) - } - - am.options.Matchers = matchers - return len(matchers) == 0 -} - -func (am *allMatcher) Criteria() interface{} { - var criterias []interface{} - for _, matcher := range am.options.Matchers { - criterias = append(criterias, matcher.Criteria()) - } - return criterias -} - -// All adds an Expect condition to exit if the content read from Console's tty -// matches all of the provided ExpectOpt, in any order. -func All(expectOpts ...ExpectOpt) ExpectOpt { - return func(opts *ExpectOpts) error { - var options ExpectOpts - for _, opt := range expectOpts { - if err := opt(&options); err != nil { - return err - } - } - - opts.Matchers = append(opts.Matchers, &allMatcher{ - options: options, - }) - return nil - } -} - -// String adds an Expect condition to exit if the content read from Console's -// tty contains any of the given strings. -func String(strs ...string) ExpectOpt { - return func(opts *ExpectOpts) error { - for _, str := range strs { - opts.Matchers = append(opts.Matchers, &stringMatcher{ - str: str, - }) - } - return nil - } -} - -// Regexp adds an Expect condition to exit if the content read from Console's -// tty matches the given Regexp. -func Regexp(res ...*regexp.Regexp) ExpectOpt { - return func(opts *ExpectOpts) error { - for _, re := range res { - opts.Matchers = append(opts.Matchers, ®expMatcher{ - re: re, - }) - } - return nil - } -} - -// RegexpPattern adds an Expect condition to exit if the content read from -// Console's tty matches the given Regexp patterns. Expect returns an error if -// the patterns were unsuccessful in compiling the Regexp. -func RegexpPattern(ps ...string) ExpectOpt { - return func(opts *ExpectOpts) error { - var res []*regexp.Regexp - for _, p := range ps { - re, err := regexp.Compile(p) - if err != nil { - return err - } - res = append(res, re) - } - return Regexp(res...)(opts) - } -} - -// Error adds an Expect condition to exit if reading from Console's tty returns -// one of the provided errors. -func Error(errs ...error) ExpectOpt { - return func(opts *ExpectOpts) error { - for _, err := range errs { - opts.Matchers = append(opts.Matchers, &errorMatcher{ - err: err, - }) - } - return nil - } -} - -// EOF adds an Expect condition to exit if io.EOF is returned from reading -// Console's tty. -func EOF(opts *ExpectOpts) error { - return Error(io.EOF)(opts) -} - -// PTSClosed adds an Expect condition to exit if we get an -// "read /dev/ptmx: input/output error" error which can occur -// on Linux while reading from the ptm after the pts is closed. -// Further Reading: -// https://github.com/kr/pty/issues/21#issuecomment-129381749 -func PTSClosed(opts *ExpectOpts) error { - opts.Matchers = append(opts.Matchers, &pathErrorMatcher{ - pathError: os.PathError{ - Op: "read", - Path: "/dev/ptmx", - Err: syscall.Errno(0x5), - }, - }) - return nil -} diff --git a/vendor/github.com/Netflix/go-expect/passthrough_pipe.go b/vendor/github.com/Netflix/go-expect/passthrough_pipe.go deleted file mode 100644 index 0056075b10..0000000000 --- a/vendor/github.com/Netflix/go-expect/passthrough_pipe.go +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright 2018 Netflix, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package expect - -import ( - "io" - "os" - "time" -) - -// PassthroughPipe is pipes data from a io.Reader and allows setting a read -// deadline. If a timeout is reached the error is returned, otherwise the error -// from the provided io.Reader is returned is passed through instead. -type PassthroughPipe struct { - reader *os.File - errC chan error -} - -// NewPassthroughPipe returns a new pipe for a io.Reader that passes through -// non-timeout errors. -func NewPassthroughPipe(reader io.Reader) (*PassthroughPipe, error) { - pipeReader, pipeWriter, err := os.Pipe() - if err != nil { - return nil, err - } - - errC := make(chan error, 1) - go func() { - defer close(errC) - _, readerErr := io.Copy(pipeWriter, reader) - if readerErr == nil { - // io.Copy reads from reader until EOF, and a successful Copy returns - // err == nil. We set it back to io.EOF to surface the error to Expect. - readerErr = io.EOF - } - - // Closing the pipeWriter will unblock the pipeReader.Read. - err = pipeWriter.Close() - if err != nil { - // If we are unable to close the pipe, and the pipe isn't already closed, - // the caller will hang indefinitely. - panic(err) - return - } - - // When an error is read from reader, we need it to passthrough the err to - // callers of (*PassthroughPipe).Read. - errC <- readerErr - }() - - return &PassthroughPipe{ - reader: pipeReader, - errC: errC, - }, nil -} - -func (pp *PassthroughPipe) Read(p []byte) (n int, err error) { - n, err = pp.reader.Read(p) - if err != nil { - if os.IsTimeout(err) { - return n, err - } - - // If the pipe is closed, this is the second time calling Read on - // PassthroughPipe, so just return the error from the os.Pipe io.Reader. - perr, ok := <-pp.errC - if !ok { - return n, err - } - - return n, perr - } - - return n, nil -} - -func (pp *PassthroughPipe) Close() error { - return pp.reader.Close() -} - -func (pp *PassthroughPipe) SetReadDeadline(t time.Time) error { - return pp.reader.SetReadDeadline(t) -} diff --git a/vendor/github.com/Netflix/go-expect/reader_lease.go b/vendor/github.com/Netflix/go-expect/reader_lease.go deleted file mode 100644 index 50180deda8..0000000000 --- a/vendor/github.com/Netflix/go-expect/reader_lease.go +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2018 Netflix, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package expect - -import ( - "context" - "fmt" - "io" -) - -// ReaderLease provides cancellable io.Readers from an underlying io.Reader. -type ReaderLease struct { - reader io.Reader - bytec chan byte -} - -// NewReaderLease returns a new ReaderLease that begins reading the given -// io.Reader. -func NewReaderLease(reader io.Reader) *ReaderLease { - rm := &ReaderLease{ - reader: reader, - bytec: make(chan byte), - } - - go func() { - for { - p := make([]byte, 1) - n, err := rm.reader.Read(p) - if err != nil { - return - } - if n == 0 { - panic("non eof read 0 bytes") - } - rm.bytec <- p[0] - } - }() - - return rm -} - -// NewReader returns a cancellable io.Reader for the underlying io.Reader. -// Readers can be cancelled without interrupting other Readers, and once -// a reader is a cancelled it will not read anymore bytes from ReaderLease's -// underlying io.Reader. -func (rm *ReaderLease) NewReader(ctx context.Context) io.Reader { - return NewChanReader(ctx, rm.bytec) -} - -type chanReader struct { - ctx context.Context - bytec <-chan byte -} - -// NewChanReader returns a io.Reader over a byte chan. If context is cancelled, -// future Reads will return io.EOF. -func NewChanReader(ctx context.Context, bytec <-chan byte) io.Reader { - return &chanReader{ - ctx: ctx, - bytec: bytec, - } -} - -func (cr *chanReader) Read(p []byte) (n int, err error) { - select { - case <-cr.ctx.Done(): - return 0, io.EOF - case b := <-cr.bytec: - if len(p) < 1 { - return 0, fmt.Errorf("cannot read into 0 len byte slice") - } - p[0] = b - return 1, nil - } -} diff --git a/vendor/github.com/Netflix/go-expect/test_log.go b/vendor/github.com/Netflix/go-expect/test_log.go deleted file mode 100644 index be3f8002f2..0000000000 --- a/vendor/github.com/Netflix/go-expect/test_log.go +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright 2018 Netflix, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package expect - -import ( - "bufio" - "io" - "strings" - "testing" -) - -// NewTestConsole returns a new Console that multiplexes the application's -// stdout to go's testing logger. Primarily so that outputs from parallel tests -// using t.Parallel() is not interleaved. -func NewTestConsole(t *testing.T, opts ...ConsoleOpt) (*Console, error) { - tf, err := NewTestWriter(t) - if err != nil { - return nil, err - } - - return NewConsole(append(opts, WithStdout(tf))...) -} - -// NewTestWriter returns an io.Writer where bytes written to the file are -// logged by go's testing logger. Bytes are flushed to the logger on line end. -func NewTestWriter(t *testing.T) (io.Writer, error) { - r, w := io.Pipe() - tw := testWriter{t} - - go func() { - defer r.Close() - - br := bufio.NewReader(r) - - for { - line, _, err := br.ReadLine() - if err != nil { - return - } - - _, err = tw.Write(line) - if err != nil { - return - } - } - }() - - return w, nil -} - -// testWriter provides a io.Writer interface to go's testing logger. -type testWriter struct { - t *testing.T -} - -func (tw testWriter) Write(p []byte) (n int, err error) { - tw.t.Log(string(p)) - return len(p), nil -} - -// StripTrailingEmptyLines returns a copy of s stripped of trailing lines that -// consist of only space characters. -func StripTrailingEmptyLines(out string) string { - lines := strings.Split(out, "\n") - if len(lines) < 2 { - return out - } - - for i := len(lines) - 1; i >= 0; i-- { - stripped := strings.Replace(lines[i], " ", "", -1) - if len(stripped) == 0 { - lines = lines[:len(lines)-1] - } else { - break - } - } - - return strings.Join(lines, "\n") -} diff --git a/vendor/github.com/ActiveState/vt10x/.travis.yml b/vendor/github.com/hinshun/vt10x/.travis.yml similarity index 100% rename from vendor/github.com/ActiveState/vt10x/.travis.yml rename to vendor/github.com/hinshun/vt10x/.travis.yml diff --git a/vendor/github.com/ActiveState/vt10x/LICENSE b/vendor/github.com/hinshun/vt10x/LICENSE similarity index 100% rename from vendor/github.com/ActiveState/vt10x/LICENSE rename to vendor/github.com/hinshun/vt10x/LICENSE diff --git a/vendor/github.com/ActiveState/vt10x/README.md b/vendor/github.com/hinshun/vt10x/README.md similarity index 100% rename from vendor/github.com/ActiveState/vt10x/README.md rename to vendor/github.com/hinshun/vt10x/README.md diff --git a/vendor/github.com/ActiveState/vt10x/color.go b/vendor/github.com/hinshun/vt10x/color.go similarity index 90% rename from vendor/github.com/ActiveState/vt10x/color.go rename to vendor/github.com/hinshun/vt10x/color.go index 4ce0d8f323..c16d3ac4a2 100644 --- a/vendor/github.com/ActiveState/vt10x/color.go +++ b/vendor/github.com/hinshun/vt10x/color.go @@ -24,12 +24,13 @@ const ( // For example, a transparent background. Otherwise, the simple case is to // map default colors to another color. const ( - DefaultFG Color = 0xff80 + iota + DefaultFG Color = 1<<24 + iota DefaultBG + DefaultCursor ) // Color maps to the ANSI colors [0, 16) and the xterm colors [16, 256). -type Color uint16 +type Color uint32 // ANSI returns true if Color is within [0, 16). func (c Color) ANSI() bool { diff --git a/vendor/github.com/ActiveState/vt10x/csi.go b/vendor/github.com/hinshun/vt10x/csi.go similarity index 81% rename from vendor/github.com/ActiveState/vt10x/csi.go rename to vendor/github.com/hinshun/vt10x/csi.go index 138cff9078..f5df174ecd 100644 --- a/vendor/github.com/ActiveState/vt10x/csi.go +++ b/vendor/github.com/hinshun/vt10x/csi.go @@ -74,26 +74,26 @@ func (t *State) handleCSI() { case '@': // ICH - insert blank char t.insertBlanks(c.arg(0, 1)) case 'A': // CUU - cursor up - t.moveTo(t.cur.x, t.cur.y-c.maxarg(0, 1)) + t.moveTo(t.cur.X, t.cur.Y-c.maxarg(0, 1)) case 'B', 'e': // CUD, VPR - cursor down - t.moveTo(t.cur.x, t.cur.y+c.maxarg(0, 1)) + t.moveTo(t.cur.X, t.cur.Y+c.maxarg(0, 1)) case 'c': // DA - device attributes if c.arg(0, 0) == 0 { // TODO: write vt102 id } case 'C', 'a': // CUF, HPR - cursor forward - t.moveTo(t.cur.x+c.maxarg(0, 1), t.cur.y) + t.moveTo(t.cur.X+c.maxarg(0, 1), t.cur.Y) case 'D': // CUB - cursor backward - t.moveTo(t.cur.x-c.maxarg(0, 1), t.cur.y) + t.moveTo(t.cur.X-c.maxarg(0, 1), t.cur.Y) case 'E': // CNL - cursor down and first col - t.moveTo(0, t.cur.y+c.arg(0, 1)) + t.moveTo(0, t.cur.Y+c.arg(0, 1)) case 'F': // CPL - cursor up and first col - t.moveTo(0, t.cur.y-c.arg(0, 1)) + t.moveTo(0, t.cur.Y-c.arg(0, 1)) case 'g': // TBC - tabulation clear switch c.arg(0, 0) { // clear current tab stop case 0: - t.tabs[t.cur.x] = false + t.tabs[t.cur.X] = false // clear all tabs case 3: for i := range t.tabs { @@ -103,7 +103,7 @@ func (t *State) handleCSI() { goto unknown } case 'G', '`': // CHA, HPA - Move to - t.moveTo(c.arg(0, 1)-1, t.cur.y) + t.moveTo(c.arg(0, 1)-1, t.cur.Y) case 'H', 'f': // CUP, HVP - move to t.moveAbsTo(c.arg(1, 1)-1, c.arg(0, 1)-1) case 'I': // CHT - cursor forward tabulation tab stops @@ -115,15 +115,15 @@ func (t *State) handleCSI() { // TODO: sel.ob.x = -1 switch c.arg(0, 0) { case 0: // below - t.clear(t.cur.x, t.cur.y, t.cols-1, t.cur.y) - if t.cur.y < t.rows-1 { - t.clear(0, t.cur.y+1, t.cols-1, t.rows-1) + t.clear(t.cur.X, t.cur.Y, t.cols-1, t.cur.Y) + if t.cur.Y < t.rows-1 { + t.clear(0, t.cur.Y+1, t.cols-1, t.rows-1) } case 1: // above - if t.cur.y > 1 { - t.clear(0, 0, t.cols-1, t.cur.y-1) + if t.cur.Y > 1 { + t.clear(0, 0, t.cols-1, t.cur.Y-1) } - t.clear(0, t.cur.y, t.cur.x, t.cur.y) + t.clear(0, t.cur.Y, t.cur.X, t.cur.Y) case 2: // all t.clear(0, 0, t.cols-1, t.rows-1) default: @@ -132,11 +132,11 @@ func (t *State) handleCSI() { case 'K': // EL - clear line switch c.arg(0, 0) { case 0: // right - t.clear(t.cur.x, t.cur.y, t.cols-1, t.cur.y) + t.clear(t.cur.X, t.cur.Y, t.cols-1, t.cur.Y) case 1: // left - t.clear(0, t.cur.y, t.cur.x, t.cur.y) + t.clear(0, t.cur.Y, t.cur.X, t.cur.Y) case 2: // all - t.clear(0, t.cur.y, t.cols-1, t.cur.y) + t.clear(0, t.cur.Y, t.cols-1, t.cur.Y) } case 'S': // SU - scroll lines up t.scrollUp(t.top, c.arg(0, 1)) @@ -149,7 +149,7 @@ func (t *State) handleCSI() { case 'M': // DL - delete lines t.deleteLines(c.arg(0, 1)) case 'X': // ECH - erase chars - t.clear(t.cur.x, t.cur.y, t.cur.x+c.arg(0, 1)-1, t.cur.y) + t.clear(t.cur.X, t.cur.Y, t.cur.X+c.arg(0, 1)-1, t.cur.Y) case 'P': // DCH - delete chars t.deleteChars(c.arg(0, 1)) case 'Z': // CBT - cursor backward tabulation tab stops @@ -158,7 +158,7 @@ func (t *State) handleCSI() { t.putTab(false) } case 'd': // VPA - move to - t.moveAbsTo(t.cur.x, c.arg(0, 1)-1) + t.moveAbsTo(t.cur.X, c.arg(0, 1)-1) case 'h': // SM - set terminal mode t.setMode(c.priv, true, c.args) case 'm': // SGR - terminal attribute (color) @@ -168,7 +168,7 @@ func (t *State) handleCSI() { case 5: // DSR - device status report t.w.Write([]byte("\033[0n")) case 6: // CPR - cursor position report - t.w.Write([]byte(fmt.Sprintf("\033[%d;%dR", t.cur.y+1, t.cur.x+1))) + t.w.Write([]byte(fmt.Sprintf("\033[%d;%dR", t.cur.Y+1, t.cur.X+1))) } case 'r': // DECSTBM - set scrolling region if c.priv { diff --git a/vendor/github.com/ActiveState/vt10x/doc.go b/vendor/github.com/hinshun/vt10x/doc.go similarity index 100% rename from vendor/github.com/ActiveState/vt10x/doc.go rename to vendor/github.com/hinshun/vt10x/doc.go diff --git a/vendor/github.com/ActiveState/vt10x/ioctl_other.go b/vendor/github.com/hinshun/vt10x/ioctl_other.go similarity index 100% rename from vendor/github.com/ActiveState/vt10x/ioctl_other.go rename to vendor/github.com/hinshun/vt10x/ioctl_other.go diff --git a/vendor/github.com/ActiveState/vt10x/ioctl_posix.go b/vendor/github.com/hinshun/vt10x/ioctl_posix.go similarity index 100% rename from vendor/github.com/ActiveState/vt10x/ioctl_posix.go rename to vendor/github.com/hinshun/vt10x/ioctl_posix.go diff --git a/vendor/github.com/ActiveState/vt10x/parse.go b/vendor/github.com/hinshun/vt10x/parse.go similarity index 59% rename from vendor/github.com/ActiveState/vt10x/parse.go rename to vendor/github.com/hinshun/vt10x/parse.go index b6eee4847a..0b841457c2 100644 --- a/vendor/github.com/ActiveState/vt10x/parse.go +++ b/vendor/github.com/hinshun/vt10x/parse.go @@ -4,39 +4,36 @@ func isControlCode(c rune) bool { return c < 0x20 || c == 0177 } -func (t *State) parse(c rune) bool { +func (t *State) parse(c rune) { t.logf("%q", string(c)) if isControlCode(c) { - wasHandled, isPrintable := t.handleControlCodes(c) - if wasHandled || t.cur.attr.mode&attrGfx == 0 { - return isPrintable + if t.handleControlCodes(c) || t.cur.Attr.Mode&attrGfx == 0 { + return } } // TODO: update selection; see st.c:2450 - if t.mode&ModeWrap != 0 && t.cur.state&cursorWrapNext != 0 { - t.lines[t.cur.y][t.cur.x].mode |= attrWrap + if t.mode&ModeWrap != 0 && t.cur.State&cursorWrapNext != 0 { + t.lines[t.cur.Y][t.cur.X].Mode |= attrWrap t.newline(true) } - if t.mode&ModeInsert != 0 && t.cur.x+1 < t.cols { + if t.mode&ModeInsert != 0 && t.cur.X+1 < t.cols { // TODO: move shiz, look at st.c:2458 t.logln("insert mode not implemented") } - t.setChar(c, &t.cur.attr, t.cur.x, t.cur.y) - if t.cur.x+1 < t.cols { - t.moveTo(t.cur.x+1, t.cur.y) + t.setChar(c, &t.cur.Attr, t.cur.X, t.cur.Y) + if t.cur.X+1 < t.cols { + t.moveTo(t.cur.X+1, t.cur.Y) } else { - t.cur.state |= cursorWrapNext + t.cur.State |= cursorWrapNext } - - return true } -func (t *State) parseEsc(c rune) bool { - if wasHandled, isPrintable := t.handleControlCodes(c); wasHandled { - return isPrintable +func (t *State) parseEsc(c rune) { + if t.handleControlCodes(c) { + return } next := t.parse t.logf("%q", string(c)) @@ -59,20 +56,20 @@ func (t *State) parseEsc(c rune) bool { '*', // set tertiary charset G2 (ignored) '+': // set quaternary charset G3 (ignored) case 'D': // IND - linefeed - if t.cur.y == t.bottom { + if t.cur.Y == t.bottom { t.scrollUp(t.top, 1) } else { - t.moveTo(t.cur.x, t.cur.y+1) + t.moveTo(t.cur.X, t.cur.Y+1) } case 'E': // NEL - next line t.newline(true) case 'H': // HTS - horizontal tab stop - t.tabs[t.cur.x] = true + t.tabs[t.cur.X] = true case 'M': // RI - reverse index - if t.cur.y == t.top { + if t.cur.Y == t.top { t.scrollDown(t.top, 1) } else { - t.moveTo(t.cur.x, t.cur.y-1) + t.moveTo(t.cur.X, t.cur.Y-1) } case 'Z': // DECID - identify terminal // TODO: write to our writer our id @@ -91,22 +88,20 @@ func (t *State) parseEsc(c rune) bool { t.logf("unknown ESC sequence '%c'\n", c) } t.state = next - return false } -func (t *State) parseEscCSI(c rune) bool { - if wasHandled, isPrintable := t.handleControlCodes(c); wasHandled { - return isPrintable +func (t *State) parseEscCSI(c rune) { + if t.handleControlCodes(c) { + return } t.logf("%q", string(c)) if t.csi.put(byte(c)) { t.state = t.parse t.handleCSI() } - return false } -func (t *State) parseEscStr(c rune) bool { +func (t *State) parseEscStr(c rune) { t.logf("%q", string(c)) switch c { case '\033': @@ -117,31 +112,29 @@ func (t *State) parseEscStr(c rune) bool { default: t.str.put(c) } - return false } -func (t *State) parseEscStrEnd(c rune) bool { - if wasHandled, isPrintable := t.handleControlCodes(c); wasHandled { - return isPrintable +func (t *State) parseEscStrEnd(c rune) { + if t.handleControlCodes(c) { + return } t.logf("%q", string(c)) t.state = t.parse if c == '\\' { t.handleSTR() } - return false } -func (t *State) parseEscAltCharset(c rune) bool { - if wasHandled, isPrintable := t.handleControlCodes(c); wasHandled { - return isPrintable +func (t *State) parseEscAltCharset(c rune) { + if t.handleControlCodes(c) { + return } t.logf("%q", string(c)) switch c { case '0': // line drawing set - t.cur.attr.mode |= attrGfx + t.cur.Attr.Mode |= attrGfx case 'B': // USASCII - t.cur.attr.mode &^= attrGfx + t.cur.Attr.Mode &^= attrGfx case 'A', // UK (ignored) '<', // multinational (ignored) '5', // Finnish (ignored) @@ -151,53 +144,41 @@ func (t *State) parseEscAltCharset(c rune) bool { t.logf("unknown alt. charset '%c'\n", c) } t.state = t.parse - return false } -func (t *State) parseEscTest(c rune) bool { - if wasHandled, isPrintable := t.handleControlCodes(c); wasHandled { - return isPrintable +func (t *State) parseEscTest(c rune) { + if t.handleControlCodes(c) { + return } // DEC screen alignment test if c == '8' { for y := 0; y < t.rows; y++ { for x := 0; x < t.cols; x++ { - t.setChar('E', &t.cur.attr, x, y) + t.setChar('E', &t.cur.Attr, x, y) } } } t.state = t.parse - return false } -// handleControlCodes handles control codes and returns two booleans -// The first boolean indicates whether the control code was handled, the second one whether -// the rune was printable -func (t *State) handleControlCodes(c rune) (bool, bool) { +func (t *State) handleControlCodes(c rune) bool { if !isControlCode(c) { - return false, true + return false } - isPrintable := false switch c { // HT case '\t': t.putTab(true) - isPrintable = true // BS case '\b': - if t.cur.x == t.cols-1 && t.Mode(ModeWrap) && t.cur.state&cursorWrapNext != 0 { - t.cur.state &^= cursorWrapNext - } else { - t.moveTo(t.cur.x-1, t.cur.y) - } + t.moveTo(t.cur.X-1, t.cur.Y) // CR case '\r': - t.moveTo(0, t.cur.y) + t.moveTo(0, t.cur.Y) // LF, VT, LF case '\f', '\v', '\n': // go to first col if mode is set t.newline(t.mode&ModeCRLF != 0) - isPrintable = true // BEL case '\a': // TODO: emit sound @@ -216,7 +197,7 @@ func (t *State) handleControlCodes(c rune) (bool, bool) { // ignore ENQ, NUL, XON, XOFF, DEL case 005, 000, 021, 023, 0177: default: - return false, true + return false } - return true, isPrintable + return true } diff --git a/vendor/github.com/ActiveState/vt10x/state.go b/vendor/github.com/hinshun/vt10x/state.go similarity index 60% rename from vendor/github.com/ActiveState/vt10x/state.go rename to vendor/github.com/hinshun/vt10x/state.go index 589c866da4..b2b40786d0 100644 --- a/vendor/github.com/ActiveState/vt10x/state.go +++ b/vendor/github.com/hinshun/vt10x/state.go @@ -62,28 +62,26 @@ const ( ChangedTitle ) -type glyph struct { - c rune - mode int16 - fg, bg Color +type Glyph struct { + Char rune + Mode int16 + FG, BG Color } -type line []glyph +type line []Glyph -type cursor struct { - attr glyph - x, y int - state uint8 +type Cursor struct { + Attr Glyph + X, Y int + State uint8 } -type parseState func(c rune) bool +type parseState func(c rune) // State represents the terminal emulation state. Use Lock/Unlock // methods to synchronize data access with VT. type State struct { DebugLogger *log.Logger - // RecordHistory is a flag that when set to true keeps a history of all lines that are scrolled out of view - RecordHistory bool w io.Writer mu sync.Mutex @@ -93,7 +91,7 @@ type State struct { altLines []line dirty []bool // line dirtiness anydirty bool - cur, curSaved cursor + cur, curSaved Cursor top, bottom int // scroll limits mode ModeFlag state parseState @@ -102,7 +100,14 @@ type State struct { numlock bool tabs []bool title string - history []line + colorOverride map[Color]Color +} + +func newState(w io.Writer) *State { + return &State{ + w: w, + colorOverride: make(map[Color]Color), + } } func (t *State) logf(format string, args ...interface{}) { @@ -136,15 +141,24 @@ func (t *State) Unlock() { t.mu.Unlock() } -// Cell returns the character code, foreground color, and background -// color at position (x, y) relative to the top left of the terminal. -func (t *State) Cell(x, y int) (ch rune, fg Color, bg Color) { - return t.lines[y][x].c, Color(t.lines[y][x].fg), Color(t.lines[y][x].bg) +// Cell returns the glyph containing the character code, foreground color, and +// background color at position (x, y) relative to the top left of the terminal. +func (t *State) Cell(x, y int) Glyph { + cell := t.lines[y][x] + fg, ok := t.colorOverride[cell.FG] + if ok { + cell.FG = fg + } + bg, ok := t.colorOverride[cell.BG] + if ok { + cell.BG = bg + } + return cell } // Cursor returns the current position of the cursor. -func (t *State) Cursor() (int, int) { - return t.cur.x, t.cur.y +func (t *State) Cursor() Cursor { + return t.cur } // CursorVisible returns the visible state of the cursor. @@ -152,9 +166,9 @@ func (t *State) CursorVisible() bool { return t.mode&ModeHide == 0 } -// Mode tests if mode is currently set. -func (t *State) Mode(mode ModeFlag) bool { - return t.mode&mode != 0 +// Mode returns the current terminal mode. +func (t *State) Mode() ModeFlag { + return t.mode } // Title returns the current title set via the tty. @@ -189,30 +203,15 @@ func (t *State) saveCursor() { func (t *State) restoreCursor() { t.cur = t.curSaved - t.moveTo(t.cur.x, t.cur.y) -} - -// WriteString processes the given string and updates the state -// This function is usually used for testing, as it also initializes the states, -// so previous state modifications are lost -func (t *State) WriteString(s string, rows, cols int) { - t.numlock = true - t.state = t.parse - t.cur.attr.fg = DefaultBG - t.cur.attr.bg = DefaultBG - t.resize(rows, cols) - t.reset() - for _, c := range []rune(s) { - t.put(c) - } + t.moveTo(t.cur.X, t.cur.Y) } -func (t *State) put(c rune) bool { - return t.state(c) +func (t *State) put(c rune) { + t.state(c) } func (t *State) putTab(forward bool) { - x := t.cur.x + x := t.cur.X if forward { if x == t.cols { return @@ -226,11 +225,11 @@ func (t *State) putTab(forward bool) { for x--; x > 0 && !t.tabs[x]; x-- { } } - t.moveTo(x, t.cur.y) + t.moveTo(x, t.cur.Y) } func (t *State) newline(firstCol bool) { - y := t.cur.y + y := t.cur.Y if y == t.bottom { cur := t.cur t.cur = t.defaultCursor() @@ -242,7 +241,7 @@ func (t *State) newline(firstCol bool) { if firstCol { t.moveTo(0, y) } else { - t.moveTo(t.cur.x, y) + t.moveTo(t.cur.X, y) } } @@ -258,8 +257,8 @@ var gfxCharTable = [62]rune{ '│', '≤', '≥', 'π', '≠', '£', '·', // x - ~ } -func (t *State) setChar(c rune, attr *glyph, x, y int) { - if attr.mode&attrGfx != 0 { +func (t *State) setChar(c rune, attr *Glyph, x, y int) { + if attr.Mode&attrGfx != 0 { if c >= 0x41 && c <= 0x7e && gfxCharTable[c-0x41] != 0 { c = gfxCharTable[c-0x41] } @@ -267,21 +266,21 @@ func (t *State) setChar(c rune, attr *glyph, x, y int) { t.changed |= ChangedScreen t.dirty[y] = true t.lines[y][x] = *attr - t.lines[y][x].c = c - //if t.options.BrightBold && attr.mode&attrBold != 0 && attr.fg < 8 { - if attr.mode&attrBold != 0 && attr.fg < 8 { - t.lines[y][x].fg = attr.fg + 8 + t.lines[y][x].Char = c + //if t.options.BrightBold && attr.Mode&attrBold != 0 && attr.FG < 8 { + if attr.Mode&attrBold != 0 && attr.FG < 8 { + t.lines[y][x].FG = attr.FG + 8 } - if attr.mode&attrReverse != 0 { - t.lines[y][x].fg = attr.bg - t.lines[y][x].bg = attr.fg + if attr.Mode&attrReverse != 0 { + t.lines[y][x].FG = attr.BG + t.lines[y][x].BG = attr.FG } } -func (t *State) defaultCursor() cursor { - c := cursor{} - c.attr.fg = DefaultFG - c.attr.bg = DefaultBG +func (t *State) defaultCursor() Cursor { + c := Cursor{} + c.Attr.FG = DefaultFG + c.Attr.BG = DefaultBG return c } @@ -299,7 +298,6 @@ func (t *State) reset() { t.mode = ModeWrap t.clear(0, 0, t.rows-1, t.cols-1) t.moveTo(0, 0) - t.history = make([]line, 0) } // TODO: definitely can improve allocs @@ -310,7 +308,7 @@ func (t *State) resize(cols, rows int) bool { if cols < 1 || rows < 1 { return false } - slide := t.cur.y - rows + 1 + slide := t.cur.Y - rows + 1 if slide > 0 { copy(t.lines, t.lines[slide:slide+rows]) copy(t.altLines, t.altLines[slide:slide+rows]) @@ -348,7 +346,7 @@ func (t *State) resize(cols, rows int) bool { t.cols = cols t.rows = rows t.setScroll(0, rows-1) - t.moveTo(t.cur.x, t.cur.y) + t.moveTo(t.cur.X, t.cur.Y) for i := 0; i < 2; i++ { if mincols < cols && minrows > 0 { t.clear(mincols, 0, cols-1, minrows-1) @@ -376,8 +374,8 @@ func (t *State) clear(x0, y0, x1, y1 int) { for y := y0; y <= y1; y++ { t.dirty[y] = true for x := x0; x <= x1; x++ { - t.lines[y][x] = t.cur.attr - t.lines[y][x].c = ' ' + t.lines[y][x] = t.cur.Attr + t.lines[y][x].Char = ' ' } } } @@ -387,7 +385,7 @@ func (t *State) clearAll() { } func (t *State) moveAbsTo(x, y int) { - if t.cur.state&cursorOrigin != 0 { + if t.cur.State&cursorOrigin != 0 { y += t.top } t.moveTo(x, y) @@ -395,7 +393,7 @@ func (t *State) moveAbsTo(x, y int) { func (t *State) moveTo(x, y int) { var miny, maxy int - if t.cur.state&cursorOrigin != 0 { + if t.cur.State&cursorOrigin != 0 { miny = t.top maxy = t.bottom } else { @@ -405,9 +403,9 @@ func (t *State) moveTo(x, y int) { x = clamp(x, 0, t.cols-1) y = clamp(y, miny, maxy) t.changed |= ChangedScreen - t.cur.state &^= cursorWrapNext - t.cur.x = x - t.cur.y = y + t.cur.State &^= cursorWrapNext + t.cur.X = x + t.cur.Y = y } func (t *State) swapScreen() { @@ -478,13 +476,6 @@ func (t *State) scrollDown(orig, n int) { func (t *State) scrollUp(orig, n int) { n = clamp(n, 0, t.bottom-orig+1) - if t.RecordHistory && orig == t.top { - for i := orig; i < orig+n; i++ { - l := make([]glyph, len(t.lines[i])) - copy(l, t.lines[i]) - t.history = append(t.history, l) - } - } t.clear(0, orig, t.cols-1, orig+n-1) t.changed |= ChangedScreen for i := orig; i <= t.bottom-n; i++ { @@ -518,9 +509,9 @@ func (t *State) setMode(priv bool, set bool, args []int) { } case 6: // DECOM - origin if set { - t.cur.state |= cursorOrigin + t.cur.State |= cursorOrigin } else { - t.cur.state &^= cursorOrigin + t.cur.State &^= cursorOrigin } t.moveAbsTo(0, 0) case 7: // DECAWM - auto wrap @@ -620,64 +611,80 @@ func (t *State) setAttr(attr []int) { a := attr[i] switch a { case 0: - t.cur.attr.mode &^= attrReverse | attrUnderline | attrBold | attrItalic | attrBlink - t.cur.attr.fg = DefaultFG - t.cur.attr.bg = DefaultBG + t.cur.Attr.Mode &^= attrReverse | attrUnderline | attrBold | attrItalic | attrBlink + t.cur.Attr.FG = DefaultFG + t.cur.Attr.BG = DefaultBG case 1: - t.cur.attr.mode |= attrBold + t.cur.Attr.Mode |= attrBold case 3: - t.cur.attr.mode |= attrItalic + t.cur.Attr.Mode |= attrItalic case 4: - t.cur.attr.mode |= attrUnderline + t.cur.Attr.Mode |= attrUnderline case 5, 6: // slow, rapid blink - t.cur.attr.mode |= attrBlink + t.cur.Attr.Mode |= attrBlink case 7: - t.cur.attr.mode |= attrReverse + t.cur.Attr.Mode |= attrReverse case 21, 22: - t.cur.attr.mode &^= attrBold + t.cur.Attr.Mode &^= attrBold case 23: - t.cur.attr.mode &^= attrItalic + t.cur.Attr.Mode &^= attrItalic case 24: - t.cur.attr.mode &^= attrUnderline + t.cur.Attr.Mode &^= attrUnderline case 25, 26: - t.cur.attr.mode &^= attrBlink + t.cur.Attr.Mode &^= attrBlink case 27: - t.cur.attr.mode &^= attrReverse + t.cur.Attr.Mode &^= attrReverse case 38: if i+2 < len(attr) && attr[i+1] == 5 { i += 2 if between(attr[i], 0, 255) { - t.cur.attr.fg = Color(attr[i]) + t.cur.Attr.FG = Color(attr[i]) } else { t.logf("bad fgcolor %d\n", attr[i]) } + } else if i+4 < len(attr) && attr[i+1] == 2 { + i += 4 + r, g, b := attr[i-2], attr[i-1], attr[i] + if !between(r, 0, 255) || !between(g, 0, 255) || !between(b, 0, 255) { + t.logf("bad fg rgb color (%d,%d,%d)\n", r, g, b) + } else { + t.cur.Attr.FG = Color(r<<16 | g<<8 | b) + } } else { t.logf("gfx attr %d unknown\n", a) } case 39: - t.cur.attr.fg = DefaultFG + t.cur.Attr.FG = DefaultFG case 48: if i+2 < len(attr) && attr[i+1] == 5 { i += 2 if between(attr[i], 0, 255) { - t.cur.attr.bg = Color(attr[i]) + t.cur.Attr.BG = Color(attr[i]) } else { t.logf("bad bgcolor %d\n", attr[i]) } + } else if i+4 < len(attr) && attr[i+1] == 2 { + i += 4 + r, g, b := attr[i-2], attr[i-1], attr[i] + if !between(r, 0, 255) || !between(g, 0, 255) || !between(b, 0, 255) { + t.logf("bad bg rgb color (%d,%d,%d)\n", r, g, b) + } else { + t.cur.Attr.BG = Color(r<<16 | g<<8 | b) + } } else { t.logf("gfx attr %d unknown\n", a) } case 49: - t.cur.attr.bg = DefaultBG + t.cur.Attr.BG = DefaultBG default: if between(a, 30, 37) { - t.cur.attr.fg = Color(a - 30) + t.cur.Attr.FG = Color(a - 30) } else if between(a, 40, 47) { - t.cur.attr.bg = Color(a - 40) + t.cur.Attr.BG = Color(a - 40) } else if between(a, 90, 97) { - t.cur.attr.fg = Color(a - 90 + 8) + t.cur.Attr.FG = Color(a - 90 + 8) } else if between(a, 100, 107) { - t.cur.attr.bg = Color(a - 100 + 8) + t.cur.Attr.BG = Color(a - 100 + 8) } else { t.logf("gfx attr %d unknown\n", a) } @@ -686,46 +693,46 @@ func (t *State) setAttr(attr []int) { } func (t *State) insertBlanks(n int) { - src := t.cur.x + src := t.cur.X dst := src + n size := t.cols - dst t.changed |= ChangedScreen - t.dirty[t.cur.y] = true + t.dirty[t.cur.Y] = true if dst >= t.cols { - t.clear(t.cur.x, t.cur.y, t.cols-1, t.cur.y) + t.clear(t.cur.X, t.cur.Y, t.cols-1, t.cur.Y) } else { - copy(t.lines[t.cur.y][dst:dst+size], t.lines[t.cur.y][src:src+size]) - t.clear(src, t.cur.y, dst-1, t.cur.y) + copy(t.lines[t.cur.Y][dst:dst+size], t.lines[t.cur.Y][src:src+size]) + t.clear(src, t.cur.Y, dst-1, t.cur.Y) } } func (t *State) insertBlankLines(n int) { - if t.cur.y < t.top || t.cur.y > t.bottom { + if t.cur.Y < t.top || t.cur.Y > t.bottom { return } - t.scrollDown(t.cur.y, n) + t.scrollDown(t.cur.Y, n) } func (t *State) deleteLines(n int) { - if t.cur.y < t.top || t.cur.y > t.bottom { + if t.cur.Y < t.top || t.cur.Y > t.bottom { return } - t.scrollUp(t.cur.y, n) + t.scrollUp(t.cur.Y, n) } func (t *State) deleteChars(n int) { - src := t.cur.x + n - dst := t.cur.x + src := t.cur.X + n + dst := t.cur.X size := t.cols - src t.changed |= ChangedScreen - t.dirty[t.cur.y] = true + t.dirty[t.cur.Y] = true if src >= t.cols { - t.clear(t.cur.x, t.cur.y, t.cols-1, t.cur.y) + t.clear(t.cur.X, t.cur.Y, t.cols-1, t.cur.Y) } else { - copy(t.lines[t.cur.y][dst:dst+size], t.lines[t.cur.y][src:src+size]) - t.clear(t.cols-n, t.cur.y, t.cols-1, t.cur.y) + copy(t.lines[t.cur.Y][dst:dst+size], t.lines[t.cur.Y][src:src+size]) + t.clear(t.cols-n, t.cur.Y, t.cols-1, t.cur.Y) } } @@ -734,160 +741,21 @@ func (t *State) setTitle(title string) { t.title = title } -// GlobalCursor returns the current position including the history -func (t *State) GlobalCursor() (int, int) { - cx := t.cur.x - if t.cur.state&cursorWrapNext != 0 { - cx++ - } - return cx, t.cur.y + len(t.history) -} - -// Size returns rows and columns of state -func (t *State) Size() (rows int, cols int) { - return t.rows, t.cols +func (t *State) Size() (cols, rows int) { + return t.cols, t.rows } -// String returns a string representation of the terminal output func (t *State) String() string { - return t.string(false, false, -1, 0) -} - -// StringBeforeCursor returns the terminal output in front of the cursor -func (t *State) StringBeforeCursor() string { - return t.string(false, true, -1, 0) -} - -// UnwrappedStringBeforeCursor returns the terminal output in front of the cursor without the automatic line wrapping -func (t *State) UnwrappedStringBeforeCursor() string { - return t.string(true, true, -1, 0) -} - -// StringToCursorFrom returns the string before the cursor starting from the global position row and col -func (t *State) StringToCursorFrom(row int, col int) string { - return t.string(false, true, row, col) -} - -// UnwrappedStringToCursorFrom returns the string before the cursor starting from the global position row and col without the automatic line wrapping -func (t *State) UnwrappedStringToCursorFrom(row int, col int) string { - return t.string(true, true, row, col) -} - -// matchRune checks if the rune `expected` matches the rune `got` -// it also returns the updated index `i` assuming that we are going backwards in an array of of expected runes (as is done in HasStringBeforeCursor()) -// if `ignoreNewlinesAndSpaces` is true, newlines and spaces that mismatch are skipped over. -func matchRune(got rune, expected []rune, i int, ignoreNewlinesAndSpaces bool) (bool, int) { - exactMatch := got == expected[i] - if exactMatch { - return true, i - 1 - } - if !ignoreNewlinesAndSpaces { - return false, i - } - - if got == ' ' { - return true, i - } - - if expected[i] == ' ' || expected[i] == '\n' || expected[i] == '\r' { - if i == 0 { - return true, -1 - } - return matchRune(got, expected, i-1, true) - } - - return false, i -} - -// HasStringBeforeCursor checks whether `m` matches the string before the cursor position -// If ignoreNewlinesAndSpaces is set to true, newline and space characters are skipped over -func (t *State) HasStringBeforeCursor(m string, ignoreNewlinesAndSpaces bool) bool { - runesToMatch := []rune(m) - // set index of current rune to be matched - i := len(runesToMatch) - 1 - - // quick check if there actually is enough data written to the terminal - if len(runesToMatch) > (len(t.history)+t.cur.y+1)*t.cols { - return false - } - - // if we are in the last column and in `cursorWrapNext` mode, - // the current character is in front of the cursor ... - onWrap := t.cur.state&cursorWrapNext != 0 - x := t.cur.x - if !onWrap { - // ... otherwise go one character back - x-- - } - y := t.cur.y - // first search for matching characters on the current screen - for ; y >= 0 && i >= 0; y-- { - for ; x >= 0 && i >= 0; x-- { - c, _, _ := t.Cell(x, y) - var isOk bool - isOk, i = matchRune(c, runesToMatch, i, ignoreNewlinesAndSpaces) - if !isOk { - return false - } - } - x = t.cols - 1 - } - // then search for matching characters in the scroll buffer (history) - for y = len(t.history) - 1; y >= 0 && i >= 0; y-- { - for x = t.cols - 1; x >= 0 && i >= 0; x-- { - c := t.history[y][x].c - var isOk bool - isOk, i = matchRune(c, runesToMatch, i, ignoreNewlinesAndSpaces) - if !isOk { - return false - } - } - } - - // ensure that we matched all the characters that we were looking for - return i == -1 -} - -func (t *State) string(unwrap bool, toCursor bool, fromRow int, fromCol int) string { t.Lock() defer t.Unlock() - lh := len(t.history) - if fromRow == -1 { - fromRow = lh - } - var view []rune - x := fromCol - for y := fromRow; y < lh; y++ { - for ; x < t.cols; x++ { - c := t.history[y][x].c - view = append(view, c) - } - x = 0 - if !unwrap { - view = append(view, '\n') - } - fromRow = lh - } - - onWrap := t.cur.state&cursorWrapNext != 0 - curX := t.cur.x - if onWrap { - curX++ - } - for y := fromRow - lh; y < t.rows && (!toCursor || y <= t.cur.y); y++ { - for ; x < t.cols; x++ { - if toCursor && x == curX && y == t.cur.y { - break - } - c, _, _ := t.Cell(x, y) - view = append(view, c) - } - x = 0 - if !unwrap { - view = append(view, '\n') + for y := 0; y < t.rows; y++ { + for x := 0; x < t.cols; x++ { + attr := t.Cell(x, y) + view = append(view, attr.Char) } + view = append(view, '\n') } return string(view) diff --git a/vendor/github.com/hinshun/vt10x/str.go b/vendor/github.com/hinshun/vt10x/str.go new file mode 100644 index 0000000000..2a42b04f63 --- /dev/null +++ b/vendor/github.com/hinshun/vt10x/str.go @@ -0,0 +1,330 @@ +package vt10x + +import ( + "fmt" + "math" + "regexp" + "strconv" + "strings" +) + +// STR sequences are similar to CSI sequences, but have string arguments (and +// as far as I can tell, don't really have a name; STR is the name I took from +// suckless which I imagine comes from rxvt or xterm). +type strEscape struct { + typ rune + buf []rune + args []string +} + +func (s *strEscape) reset() { + s.typ = 0 + s.buf = s.buf[:0] + s.args = nil +} + +func (s *strEscape) put(c rune) { + // TODO: improve allocs with an array backed slice; bench first + if len(s.buf) < 256 { + s.buf = append(s.buf, c) + } + // Going by st, it is better to remain silent when the STR sequence is not + // ended so that it is apparent to users something is wrong. The length sanity + // check ensures we don't absorb the entire stream into memory. + // TODO: see what rxvt or xterm does +} + +func (s *strEscape) parse() { + s.args = strings.Split(string(s.buf), ";") +} + +func (s *strEscape) arg(i, def int) int { + if i >= len(s.args) || i < 0 { + return def + } + i, err := strconv.Atoi(s.args[i]) + if err != nil { + return def + } + return i +} + +func (s *strEscape) argString(i int, def string) string { + if i >= len(s.args) || i < 0 { + return def + } + return s.args[i] +} + +func (t *State) handleSTR() { + s := &t.str + s.parse() + + switch s.typ { + case ']': // OSC - operating system command + var p *string + switch d := s.arg(0, 0); d { + case 0, 1, 2: + title := s.argString(1, "") + if title != "" { + t.setTitle(title) + } + case 10: + if len(s.args) < 2 { + break + } + + c := s.argString(1, "") + p := &c + if p != nil && *p == "?" { + t.oscColorResponse(int(DefaultFG), 10) + } else if err := t.setColorName(int(DefaultFG), p); err != nil { + t.logf("invalid foreground color: %s\n", maybe(p)) + } else { + // TODO: redraw + } + case 11: + if len(s.args) < 2 { + break + } + + c := s.argString(1, "") + p := &c + if p != nil && *p == "?" { + t.oscColorResponse(int(DefaultBG), 11) + } else if err := t.setColorName(int(DefaultBG), p); err != nil { + t.logf("invalid cursor color: %s\n", maybe(p)) + } else { + // TODO: redraw + } + // case 12: + // if len(s.args) < 2 { + // break + // } + + // c := s.argString(1, "") + // p := &c + // if p != nil && *p == "?" { + // t.oscColorResponse(int(DefaultCursor), 12) + // } else if err := t.setColorName(int(DefaultCursor), p); err != nil { + // t.logf("invalid background color: %s\n", p) + // } else { + // // TODO: redraw + // } + case 4: // color set + if len(s.args) < 3 { + break + } + + c := s.argString(2, "") + p = &c + fallthrough + case 104: // color reset + j := -1 + if len(s.args) > 1 { + j = s.arg(1, 0) + } + if p != nil && *p == "?" { // report + t.osc4ColorResponse(j) + } else if err := t.setColorName(j, p); err != nil { + if !(d == 104 && len(s.args) <= 1) { + t.logf("invalid color j=%d, p=%s\n", j, maybe(p)) + } + } else { + // TODO: redraw + } + default: + t.logf("unknown OSC command %d\n", d) + // TODO: s.dump() + } + case 'k': // old title set compatibility + title := s.argString(0, "") + if title != "" { + t.setTitle(title) + } + default: + // TODO: Ignore these codes instead of complain? + // 'P': // DSC - device control string + // '_': // APC - application program command + // '^': // PM - privacy message + + t.logf("unhandled STR sequence '%c'\n", s.typ) + // t.str.dump() + } +} + +func (t *State) setColorName(j int, p *string) error { + if !between(j, 0, 1<<24) { + return fmt.Errorf("invalid color value %d", j) + } + + if p == nil { + // restore color + delete(t.colorOverride, Color(j)) + } else { + // set color + r, g, b, err := parseColor(*p) + if err != nil { + return err + } + t.colorOverride[Color(j)] = Color(r<<16 | g<<8 | b) + } + + return nil +} + +func (t *State) oscColorResponse(j, num int) { + if j < 0 { + t.logf("failed to fetch osc color %d\n", j) + return + } + + k, ok := t.colorOverride[Color(j)] + if ok { + j = int(k) + } + + r, g, b := rgb(j) + t.w.Write([]byte(fmt.Sprintf("\033]%d;rgb:%02x%02x/%02x%02x/%02x%02x\007", num, r, r, g, g, b, b))) +} + +func (t *State) osc4ColorResponse(j int) { + if j < 0 { + t.logf("failed to fetch osc4 color %d\n", j) + return + } + + k, ok := t.colorOverride[Color(j)] + if ok { + j = int(k) + } + + r, g, b := rgb(j) + t.w.Write([]byte(fmt.Sprintf("\033]4;%d;rgb:%02x%02x/%02x%02x/%02x%02x\007", j, r, r, g, g, b, b))) +} + +func rgb(j int) (r, g, b int) { + return (j >> 16) & 0xff, (j >> 8) & 0xff, j & 0xff +} + +var ( + RGBPattern = regexp.MustCompile(`^([\da-f]{1})\/([\da-f]{1})\/([\da-f]{1})$|^([\da-f]{2})\/([\da-f]{2})\/([\da-f]{2})$|^([\da-f]{3})\/([\da-f]{3})\/([\da-f]{3})$|^([\da-f]{4})\/([\da-f]{4})\/([\da-f]{4})$`) + HashPattern = regexp.MustCompile(`[\da-f]`) +) + +func parseColor(p string) (r, g, b int, err error) { + if len(p) == 0 { + err = fmt.Errorf("empty color spec") + return + } + + low := strings.ToLower(p) + if strings.HasPrefix(low, "rgb:") { + low = low[4:] + sm := RGBPattern.FindAllStringSubmatch(low, -1) + if len(sm) != 1 || len(sm[0]) == 0 { + err = fmt.Errorf("invalid rgb color spec: %s", p) + return + } + m := sm[0] + + var base float64 + if len(m[1]) > 0 { + base = 15 + } else if len(m[4]) > 0 { + base = 255 + } else if len(m[7]) > 0 { + base = 4095 + } else { + base = 65535 + } + + r64, err := strconv.ParseInt(firstNonEmpty(m[1], m[4], m[7], m[10]), 16, 0) + if err != nil { + return r, g, b, err + } + + g64, err := strconv.ParseInt(firstNonEmpty(m[2], m[5], m[8], m[11]), 16, 0) + if err != nil { + return r, g, b, err + } + + b64, err := strconv.ParseInt(firstNonEmpty(m[3], m[6], m[9], m[12]), 16, 0) + if err != nil { + return r, g, b, err + } + + r = int(math.Round(float64(r64) / base * 255)) + g = int(math.Round(float64(g64) / base * 255)) + b = int(math.Round(float64(b64) / base * 255)) + return r, g, b, nil + } else if strings.HasPrefix(low, "#") { + low = low[1:] + m := HashPattern.FindAllString(low, -1) + if !oneOf(len(m), []int{3, 6, 9, 12}) { + err = fmt.Errorf("invalid hash color spec: %s", p) + return + } + + adv := len(low) / 3 + for i := 0; i < 3; i++ { + c, err := strconv.ParseInt(low[adv*i:adv*i+adv], 16, 0) + if err != nil { + return r, g, b, err + } + + var v int64 + switch adv { + case 1: + v = c << 4 + case 2: + v = c + case 3: + v = c >> 4 + default: + v = c >> 8 + } + + switch i { + case 0: + r = int(v) + case 1: + g = int(v) + case 2: + b = int(v) + } + } + return + } else { + err = fmt.Errorf("invalid color spec: %s", p) + return + } +} + +func maybe(p *string) string { + if p == nil { + return "" + } + return *p +} + +func firstNonEmpty(strs ...string) string { + if len(strs) == 0 { + return "" + } + for _, str := range strs { + if len(str) > 0 { + return str + } + } + return strs[len(strs)-1] +} + +func oneOf(v int, is []int) bool { + for _, i := range is { + if v == i { + return true + } + } + return false +} diff --git a/vendor/github.com/hinshun/vt10x/vt.go b/vendor/github.com/hinshun/vt10x/vt.go new file mode 100644 index 0000000000..c4e58dd6a4 --- /dev/null +++ b/vendor/github.com/hinshun/vt10x/vt.go @@ -0,0 +1,89 @@ +package vt10x + +import ( + "bufio" + "fmt" + "io" + "io/ioutil" +) + +// Terminal represents the virtual terminal emulator. +type Terminal interface { + // View displays the virtual terminal. + View + + // Write parses input and writes terminal changes to state. + io.Writer + + // Parse blocks on read on pty or io.Reader, then parses sequences until + // buffer empties. State is locked as soon as first rune is read, and unlocked + // when buffer is empty. + Parse(bf *bufio.Reader) error +} + +// View represents the view of the virtual terminal emulator. +type View interface { + // String dumps the virtual terminal contents. + fmt.Stringer + + // Size returns the size of the virtual terminal. + Size() (cols, rows int) + + // Resize changes the size of the virtual terminal. + Resize(cols, rows int) + + // Mode returns the current terminal mode.// + Mode() ModeFlag + + // Title represents the title of the console window. + Title() string + + // Cell returns the glyph containing the character code, foreground color, and + // background color at position (x, y) relative to the top left of the terminal. + Cell(x, y int) Glyph + + // Cursor returns the current position of the cursor. + Cursor() Cursor + + // CursorVisible returns the visible state of the cursor. + CursorVisible() bool + + // Lock locks the state object's mutex. + Lock() + + // Unlock resets change flags and unlocks the state object's mutex. + Unlock() +} + +type TerminalOption func(*TerminalInfo) + +type TerminalInfo struct { + w io.Writer + cols, rows int +} + +func WithWriter(w io.Writer) TerminalOption { + return func(info *TerminalInfo) { + info.w = w + } +} + +func WithSize(cols, rows int) TerminalOption { + return func(info *TerminalInfo) { + info.cols = cols + info.rows = rows + } +} + +// New returns a new virtual terminal emulator. +func New(opts ...TerminalOption) Terminal { + info := TerminalInfo{ + w: ioutil.Discard, + cols: 80, + rows: 24, + } + for _, opt := range opts { + opt(&info) + } + return newTerminal(info) +} diff --git a/vendor/github.com/hinshun/vt10x/vt_other.go b/vendor/github.com/hinshun/vt10x/vt_other.go new file mode 100644 index 0000000000..c9d364ee53 --- /dev/null +++ b/vendor/github.com/hinshun/vt10x/vt_other.go @@ -0,0 +1,107 @@ +// +build plan9 nacl windows + +package vt10x + +import ( + "bufio" + "bytes" + "io" + "unicode" + "unicode/utf8" +) + +type terminal struct { + *State +} + +func newTerminal(info TerminalInfo) *terminal { + t := &terminal{newState(info.w)} + t.init(info.cols, info.rows) + return t +} + +func (t *terminal) init(cols, rows int) { + t.numlock = true + t.state = t.parse + t.cur.Attr.FG = DefaultFG + t.cur.Attr.BG = DefaultBG + t.Resize(cols, rows) + t.reset() +} + +func (t *terminal) Write(p []byte) (int, error) { + var written int + r := bytes.NewReader(p) + t.lock() + defer t.unlock() + for { + c, sz, err := r.ReadRune() + if err != nil { + if err == io.EOF { + break + } + return written, err + } + written += sz + if c == unicode.ReplacementChar && sz == 1 { + if r.Len() == 0 { + // not enough bytes for a full rune + return written - 1, nil + } + t.logln("invalid utf8 sequence") + continue + } + t.put(c) + } + return written, nil +} + +// TODO: add tests for expected blocking behavior +func (t *terminal) Parse(br *bufio.Reader) error { + var locked bool + defer func() { + if locked { + t.unlock() + } + }() + for { + c, sz, err := br.ReadRune() + if err != nil { + return err + } + if c == unicode.ReplacementChar && sz == 1 { + t.logln("invalid utf8 sequence") + break + } + if !locked { + t.lock() + locked = true + } + + // put rune for parsing and update state + t.put(c) + + // break if our buffer is empty, or if buffer contains an + // incomplete rune. + n := br.Buffered() + if n == 0 || (n < 4 && !fullRuneBuffered(br)) { + break + } + } + return nil +} + +func fullRuneBuffered(br *bufio.Reader) bool { + n := br.Buffered() + buf, err := br.Peek(n) + if err != nil { + return false + } + return utf8.FullRune(buf) +} + +func (t *terminal) Resize(cols, rows int) { + t.lock() + defer t.unlock() + _ = t.resize(cols, rows) +} diff --git a/vendor/github.com/hinshun/vt10x/vt_posix.go b/vendor/github.com/hinshun/vt10x/vt_posix.go new file mode 100644 index 0000000000..80644f4bdc --- /dev/null +++ b/vendor/github.com/hinshun/vt10x/vt_posix.go @@ -0,0 +1,108 @@ +// +build linux darwin dragonfly solaris openbsd netbsd freebsd + +package vt10x + +import ( + "bufio" + "bytes" + "io" + "unicode" + "unicode/utf8" +) + +type terminal struct { + *State +} + +func newTerminal(info TerminalInfo) *terminal { + t := &terminal{newState(info.w)} + t.init(info.cols, info.rows) + return t +} + +func (t *terminal) init(cols, rows int) { + t.numlock = true + t.state = t.parse + t.cur.Attr.FG = DefaultFG + t.cur.Attr.BG = DefaultBG + t.Resize(cols, rows) + t.reset() +} + +// Write parses input and writes terminal changes to state. +func (t *terminal) Write(p []byte) (int, error) { + var written int + r := bytes.NewReader(p) + t.lock() + defer t.unlock() + for { + c, sz, err := r.ReadRune() + if err != nil { + if err == io.EOF { + break + } + return written, err + } + written += sz + if c == unicode.ReplacementChar && sz == 1 { + if r.Len() == 0 { + // not enough bytes for a full rune + return written - 1, nil + } + t.logln("invalid utf8 sequence") + continue + } + t.put(c) + } + return written, nil +} + +// TODO: add tests for expected blocking behavior +func (t *terminal) Parse(br *bufio.Reader) error { + var locked bool + defer func() { + if locked { + t.unlock() + } + }() + for { + c, sz, err := br.ReadRune() + if err != nil { + return err + } + if c == unicode.ReplacementChar && sz == 1 { + t.logln("invalid utf8 sequence") + break + } + if !locked { + t.lock() + locked = true + } + + // put rune for parsing and update state + t.put(c) + + // break if our buffer is empty, or if buffer contains an + // incomplete rune. + n := br.Buffered() + if n == 0 || (n < 4 && !fullRuneBuffered(br)) { + break + } + } + return nil +} + +func fullRuneBuffered(br *bufio.Reader) bool { + n := br.Buffered() + buf, err := br.Peek(n) + if err != nil { + return false + } + return utf8.FullRune(buf) +} + +func (t *terminal) Resize(cols, rows int) { + t.lock() + defer t.unlock() + _ = t.resize(cols, rows) +} diff --git a/vendor/github.com/kr/pty/README.md b/vendor/github.com/kr/pty/README.md deleted file mode 100644 index 64466c3282..0000000000 --- a/vendor/github.com/kr/pty/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# pty - -This Go module has moved to . - -Existing clients will continue to work. - -New clients should use the new module import path -`github.com/creack/pty`. - diff --git a/vendor/github.com/kr/pty/shim.go b/vendor/github.com/kr/pty/shim.go deleted file mode 100644 index 32e04262e0..0000000000 --- a/vendor/github.com/kr/pty/shim.go +++ /dev/null @@ -1,76 +0,0 @@ -// Package pty is a wrapper for github.com/creack/pty, which provides -// functions for working with Unix terminals. -// -// This package is deprecated. Existing clients will continue to work, -// but no further updates will happen here. New clients should use -// github.com/creack/pty directly. -package pty - -import ( - "os" - "os/exec" - - "github.com/creack/pty" - newpty "github.com/creack/pty" -) - -// ErrUnsupported is returned if a function is not available on the -// current platform. -// -// Deprecated; please use github.com/creack/pty instead. -var ErrUnsupported = pty.ErrUnsupported - -// Winsize describes the terminal size. -// -// Deprecated; please use github.com/creack/pty instead. -type Winsize = pty.Winsize - -// Getsize returns the number of rows (lines) and cols (positions in -// each line) in terminal t. -// -// Deprecated; please use github.com/creack/pty instead. -func Getsize(t *os.File) (rows, cols int, err error) { return pty.Getsize(t) } - -// GetsizeFull returns the full terminal size description. -// -// Deprecated; please use github.com/creack/pty instead. -func GetsizeFull(t *os.File) (size *Winsize, err error) { - return pty.GetsizeFull(t) -} - -// InheritSize applies the terminal size of pty to tty. This should be -// run in a signal handler for syscall.SIGWINCH to automatically -// resize the tty when the pty receives a window size change -// notification. -// -// Deprecated; please use github.com/creack/pty instead. -func InheritSize(pty, tty *os.File) error { return newpty.InheritSize(pty, tty) } - -// Opens a pty and its corresponding tty. -// -// Deprecated; please use github.com/creack/pty instead. -func Open() (pty, tty *os.File, err error) { return newpty.Open() } - -// Setsize resizes t to s. -// -// Deprecated; please use github.com/creack/pty instead. -func Setsize(t *os.File, ws *Winsize) error { return pty.Setsize(t, ws) } - -// Start assigns a pseudo-terminal tty os.File to c.Stdin, c.Stdout, -// and c.Stderr, calls c.Start, and returns the File of the tty's -// corresponding pty. -// -// Deprecated; please use github.com/creack/pty instead. -func Start(c *exec.Cmd) (pty *os.File, err error) { return newpty.Start(c) } - -// StartWithSize assigns a pseudo-terminal tty os.File to c.Stdin, -// c.Stdout, and c.Stderr, calls c.Start, and returns the File of the -// tty's corresponding pty. -// -// This will resize the pty to the specified size before starting the -// command. -// -// Deprecated; please use github.com/creack/pty instead. -func StartWithSize(c *exec.Cmd, sz *Winsize) (pty *os.File, err error) { - return newpty.StartWithSize(c, sz) -} diff --git a/vendor/github.com/shirou/gopsutil/v3/common/env.go b/vendor/github.com/shirou/gopsutil/v3/common/env.go new file mode 100644 index 0000000000..4b5f4980c2 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/common/env.go @@ -0,0 +1,23 @@ +package common + +type EnvKeyType string + +// EnvKey is a context key that can be used to set programmatically the environment +// gopsutil relies on to perform calls against the OS. +// Example of use: +// +// ctx := context.WithValue(context.Background(), common.EnvKey, EnvMap{common.HostProcEnvKey: "/myproc"}) +// avg, err := load.AvgWithContext(ctx) +var EnvKey = EnvKeyType("env") + +const ( + HostProcEnvKey EnvKeyType = "HOST_PROC" + HostSysEnvKey EnvKeyType = "HOST_SYS" + HostEtcEnvKey EnvKeyType = "HOST_ETC" + HostVarEnvKey EnvKeyType = "HOST_VAR" + HostRunEnvKey EnvKeyType = "HOST_RUN" + HostDevEnvKey EnvKeyType = "HOST_DEV" + HostRootEnvKey EnvKeyType = "HOST_ROOT" +) + +type EnvMap map[EnvKeyType]string diff --git a/vendor/github.com/shirou/gopsutil/v3/cpu/cpu_aix_nocgo.go b/vendor/github.com/shirou/gopsutil/v3/cpu/cpu_aix_nocgo.go index d158000eae..1a291532ad 100644 --- a/vendor/github.com/shirou/gopsutil/v3/cpu/cpu_aix_nocgo.go +++ b/vendor/github.com/shirou/gopsutil/v3/cpu/cpu_aix_nocgo.go @@ -6,8 +6,8 @@ package cpu import ( "context" "regexp" - "strings" "strconv" + "strings" "github.com/shirou/gopsutil/v3/internal/common" ) @@ -28,19 +28,19 @@ func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) { } ret := TimesStat{CPU: "cpu-total"} - h := whiteSpaces.Split(lines[len(lines)-3], -1) // headers - v := whiteSpaces.Split(lines[len(lines)-2], -1) // values + h := whiteSpaces.Split(lines[len(lines)-3], -1) // headers + v := whiteSpaces.Split(lines[len(lines)-2], -1) // values for i, header := range h { if t, err := strconv.ParseFloat(v[i], 64); err == nil { switch header { - case `%usr`: - ret.User = t - case `%sys`: - ret.System = t - case `%wio`: - ret.Iowait = t - case `%idle`: - ret.Idle = t + case `%usr`: + ret.User = t + case `%sys`: + ret.System = t + case `%wio`: + ret.Iowait = t + case `%idle`: + ret.Idle = t } } } diff --git a/vendor/github.com/shirou/gopsutil/v3/cpu/cpu_darwin.go b/vendor/github.com/shirou/gopsutil/v3/cpu/cpu_darwin.go index 7acb258d90..41f395e5e0 100644 --- a/vendor/github.com/shirou/gopsutil/v3/cpu/cpu_darwin.go +++ b/vendor/github.com/shirou/gopsutil/v3/cpu/cpu_darwin.go @@ -8,6 +8,7 @@ import ( "strconv" "strings" + "github.com/shoenig/go-m1cpu" "github.com/tklauser/go-sysconf" "golang.org/x/sys/unix" ) @@ -85,11 +86,15 @@ func InfoWithContext(ctx context.Context) ([]InfoStat, error) { c.CacheSize = int32(cacheSize) c.VendorID, _ = unix.Sysctl("machdep.cpu.vendor") - // Use the rated frequency of the CPU. This is a static value and does not - // account for low power or Turbo Boost modes. - cpuFrequency, err := unix.SysctlUint64("hw.cpufrequency") - if err == nil { - c.Mhz = float64(cpuFrequency) / 1000000.0 + if m1cpu.IsAppleSilicon() { + c.Mhz = float64(m1cpu.PCoreHz() / 1_000_000) + } else { + // Use the rated frequency of the CPU. This is a static value and does not + // account for low power or Turbo Boost modes. + cpuFrequency, err := unix.SysctlUint64("hw.cpufrequency") + if err == nil { + c.Mhz = float64(cpuFrequency) / 1000000.0 + } } return append(ret, c), nil diff --git a/vendor/github.com/shirou/gopsutil/v3/cpu/cpu_linux.go b/vendor/github.com/shirou/gopsutil/v3/cpu/cpu_linux.go index 4f26230d6b..b5a20e366f 100644 --- a/vendor/github.com/shirou/gopsutil/v3/cpu/cpu_linux.go +++ b/vendor/github.com/shirou/gopsutil/v3/cpu/cpu_linux.go @@ -11,12 +11,78 @@ import ( "strconv" "strings" - "github.com/shirou/gopsutil/v3/internal/common" "github.com/tklauser/go-sysconf" + + "github.com/shirou/gopsutil/v3/internal/common" ) var ClocksPerSec = float64(100) +var armModelToModelName = map[uint64]string{ + 0x810: "ARM810", + 0x920: "ARM920", + 0x922: "ARM922", + 0x926: "ARM926", + 0x940: "ARM940", + 0x946: "ARM946", + 0x966: "ARM966", + 0xa20: "ARM1020", + 0xa22: "ARM1022", + 0xa26: "ARM1026", + 0xb02: "ARM11 MPCore", + 0xb36: "ARM1136", + 0xb56: "ARM1156", + 0xb76: "ARM1176", + 0xc05: "Cortex-A5", + 0xc07: "Cortex-A7", + 0xc08: "Cortex-A8", + 0xc09: "Cortex-A9", + 0xc0d: "Cortex-A17", + 0xc0f: "Cortex-A15", + 0xc0e: "Cortex-A17", + 0xc14: "Cortex-R4", + 0xc15: "Cortex-R5", + 0xc17: "Cortex-R7", + 0xc18: "Cortex-R8", + 0xc20: "Cortex-M0", + 0xc21: "Cortex-M1", + 0xc23: "Cortex-M3", + 0xc24: "Cortex-M4", + 0xc27: "Cortex-M7", + 0xc60: "Cortex-M0+", + 0xd01: "Cortex-A32", + 0xd02: "Cortex-A34", + 0xd03: "Cortex-A53", + 0xd04: "Cortex-A35", + 0xd05: "Cortex-A55", + 0xd06: "Cortex-A65", + 0xd07: "Cortex-A57", + 0xd08: "Cortex-A72", + 0xd09: "Cortex-A73", + 0xd0a: "Cortex-A75", + 0xd0b: "Cortex-A76", + 0xd0c: "Neoverse-N1", + 0xd0d: "Cortex-A77", + 0xd0e: "Cortex-A76AE", + 0xd13: "Cortex-R52", + 0xd20: "Cortex-M23", + 0xd21: "Cortex-M33", + 0xd40: "Neoverse-V1", + 0xd41: "Cortex-A78", + 0xd42: "Cortex-A78AE", + 0xd43: "Cortex-A65AE", + 0xd44: "Cortex-X1", + 0xd46: "Cortex-A510", + 0xd47: "Cortex-A710", + 0xd48: "Cortex-X2", + 0xd49: "Neoverse-N2", + 0xd4a: "Neoverse-E1", + 0xd4b: "Cortex-A78C", + 0xd4c: "Cortex-X1C", + 0xd4d: "Cortex-A715", + 0xd4e: "Cortex-X3", +} + func init() { clkTck, err := sysconf.Sysconf(sysconf.SC_CLK_TCK) // ignore errors @@ -30,7 +96,7 @@ func Times(percpu bool) ([]TimesStat, error) { } func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) { - filename := common.HostProc("stat") + filename := common.HostProcWithContext(ctx, "stat") lines := []string{} if percpu { statlines, err := common.ReadLines(filename) @@ -60,17 +126,17 @@ func TimesWithContext(ctx context.Context, percpu bool) ([]TimesStat, error) { return ret, nil } -func sysCPUPath(cpu int32, relPath string) string { - return common.HostSys(fmt.Sprintf("devices/system/cpu/cpu%d", cpu), relPath) +func sysCPUPath(ctx context.Context, cpu int32, relPath string) string { + return common.HostSysWithContext(ctx, fmt.Sprintf("devices/system/cpu/cpu%d", cpu), relPath) } -func finishCPUInfo(c *InfoStat) { +func finishCPUInfo(ctx context.Context, c *InfoStat) { var lines []string var err error var value float64 if len(c.CoreID) == 0 { - lines, err = common.ReadLines(sysCPUPath(c.CPU, "topology/core_id")) + lines, err = common.ReadLines(sysCPUPath(ctx, c.CPU, "topology/core_id")) if err == nil { c.CoreID = lines[0] } @@ -79,7 +145,7 @@ func finishCPUInfo(c *InfoStat) { // override the value of c.Mhz with cpufreq/cpuinfo_max_freq regardless // of the value from /proc/cpuinfo because we want to report the maximum // clock-speed of the CPU for c.Mhz, matching the behaviour of Windows - lines, err = common.ReadLines(sysCPUPath(c.CPU, "cpufreq/cpuinfo_max_freq")) + lines, err = common.ReadLines(sysCPUPath(ctx, c.CPU, "cpufreq/cpuinfo_max_freq")) // if we encounter errors below such as there are no cpuinfo_max_freq file, // we just ignore. so let Mhz is 0. if err != nil || len(lines) == 0 { @@ -107,7 +173,7 @@ func Info() ([]InfoStat, error) { } func InfoWithContext(ctx context.Context) ([]InfoStat, error) { - filename := common.HostProc("cpuinfo") + filename := common.HostProcWithContext(ctx, "cpuinfo") lines, _ := common.ReadLines(filename) var ret []InfoStat @@ -125,9 +191,9 @@ func InfoWithContext(ctx context.Context) ([]InfoStat, error) { switch key { case "Processor": processorName = value - case "processor": + case "processor", "cpu number": if c.CPU >= 0 { - finishCPUInfo(&c) + finishCPUInfo(ctx, &c) ret = append(ret, c) } c = InfoStat{Cores: 1, ModelName: processorName} @@ -138,6 +204,9 @@ func InfoWithContext(ctx context.Context) ([]InfoStat, error) { c.CPU = int32(t) case "vendorId", "vendor_id": c.VendorID = value + if strings.Contains(value, "S390") { + processorName = "S390" + } case "CPU implementer": if v, err := strconv.ParseUint(value, 0, 8); err == nil { switch v { @@ -177,10 +246,20 @@ func InfoWithContext(ctx context.Context) ([]InfoStat, error) { c.Family = value case "model", "CPU part": c.Model = value - case "model name", "cpu": + // if CPU is arm based, model name is found via model number. refer to: arch/arm64/kernel/cpuinfo.c + if c.VendorID == "ARM" { + if v, err := strconv.ParseUint(c.Model, 0, 16); err == nil { + modelName, exist := armModelToModelName[v] + if exist { + c.ModelName = modelName + } else { + c.ModelName = "Undefined" + } + } + } + case "Model Name", "model name", "cpu": c.ModelName = value - if strings.Contains(value, "POWER8") || - strings.Contains(value, "POWER7") { + if strings.Contains(value, "POWER") { c.Model = strings.Split(value, " ")[0] c.Family = "POWER" c.VendorID = "IBM" @@ -197,7 +276,7 @@ func InfoWithContext(ctx context.Context) ([]InfoStat, error) { return ret, err } c.Stepping = int32(t) - case "cpu MHz", "clock": + case "cpu MHz", "clock", "cpu MHz dynamic": // treat this as the fallback value, thus we ignore error if t, err := strconv.ParseFloat(strings.Replace(value, "MHz", "", 1), 64); err == nil { c.Mhz = t @@ -221,7 +300,7 @@ func InfoWithContext(ctx context.Context) ([]InfoStat, error) { } } if c.CPU >= 0 { - finishCPUInfo(&c) + finishCPUInfo(ctx, &c) ret = append(ret, c) } return ret, nil @@ -310,7 +389,7 @@ func CountsWithContext(ctx context.Context, logical bool) (int, error) { if logical { ret := 0 // https://github.com/giampaolo/psutil/blob/d01a9eaa35a8aadf6c519839e987a49d8be2d891/psutil/_pslinux.py#L599 - procCpuinfo := common.HostProc("cpuinfo") + procCpuinfo := common.HostProcWithContext(ctx, "cpuinfo") lines, err := common.ReadLines(procCpuinfo) if err == nil { for _, line := range lines { @@ -324,7 +403,7 @@ func CountsWithContext(ctx context.Context, logical bool) (int, error) { } } if ret == 0 { - procStat := common.HostProc("stat") + procStat := common.HostProcWithContext(ctx, "stat") lines, err = common.ReadLines(procStat) if err != nil { return 0, err @@ -345,7 +424,7 @@ func CountsWithContext(ctx context.Context, logical bool) (int, error) { // https://github.com/giampaolo/psutil/pull/1727#issuecomment-707624964 // https://lkml.org/lkml/2019/2/26/41 for _, glob := range []string{"devices/system/cpu/cpu[0-9]*/topology/core_cpus_list", "devices/system/cpu/cpu[0-9]*/topology/thread_siblings_list"} { - if files, err := filepath.Glob(common.HostSys(glob)); err == nil { + if files, err := filepath.Glob(common.HostSysWithContext(ctx, glob)); err == nil { for _, file := range files { lines, err := common.ReadLines(file) if err != nil || len(lines) != 1 { @@ -360,7 +439,7 @@ func CountsWithContext(ctx context.Context, logical bool) (int, error) { } } // https://github.com/giampaolo/psutil/blob/122174a10b75c9beebe15f6c07dcf3afbe3b120d/psutil/_pslinux.py#L631-L652 - filename := common.HostProc("cpuinfo") + filename := common.HostProcWithContext(ctx, "cpuinfo") lines, err := common.ReadLines(filename) if err != nil { return 0, err diff --git a/vendor/github.com/shirou/gopsutil/v3/cpu/cpu_windows.go b/vendor/github.com/shirou/gopsutil/v3/cpu/cpu_windows.go index d1a0e4cdbb..e10612fd19 100644 --- a/vendor/github.com/shirou/gopsutil/v3/cpu/cpu_windows.go +++ b/vendor/github.com/shirou/gopsutil/v3/cpu/cpu_windows.go @@ -14,8 +14,7 @@ import ( ) var ( - procGetActiveProcessorCount = common.Modkernel32.NewProc("GetActiveProcessorCount") - procGetNativeSystemInfo = common.Modkernel32.NewProc("GetNativeSystemInfo") + procGetNativeSystemInfo = common.Modkernel32.NewProc("GetNativeSystemInfo") ) type win32_Processor struct { @@ -204,15 +203,12 @@ type systemInfo struct { func CountsWithContext(ctx context.Context, logical bool) (int, error) { if logical { // https://github.com/giampaolo/psutil/blob/d01a9eaa35a8aadf6c519839e987a49d8be2d891/psutil/_psutil_windows.c#L97 - err := procGetActiveProcessorCount.Find() - if err == nil { // Win7+ - ret, _, _ := procGetActiveProcessorCount.Call(uintptr(0xffff)) // ALL_PROCESSOR_GROUPS is 0xffff according to Rust's winapi lib https://docs.rs/winapi/*/x86_64-pc-windows-msvc/src/winapi/shared/ntdef.rs.html#120 - if ret != 0 { - return int(ret), nil - } + ret := windows.GetActiveProcessorCount(windows.ALL_PROCESSOR_GROUPS) + if ret != 0 { + return int(ret), nil } var systemInfo systemInfo - _, _, err = procGetNativeSystemInfo.Call(uintptr(unsafe.Pointer(&systemInfo))) + _, _, err := procGetNativeSystemInfo.Call(uintptr(unsafe.Pointer(&systemInfo))) if systemInfo.dwNumberOfProcessors == 0 { return 0, err } diff --git a/vendor/github.com/shirou/gopsutil/v3/internal/common/binary.go b/vendor/github.com/shirou/gopsutil/v3/internal/common/binary.go index 446c3597fd..5e8d43db83 100644 --- a/vendor/github.com/shirou/gopsutil/v3/internal/common/binary.go +++ b/vendor/github.com/shirou/gopsutil/v3/internal/common/binary.go @@ -21,6 +21,7 @@ package common // high-performance serialization, especially for large data structures, // should look at more advanced solutions such as the encoding/gob // package or protocol buffers. + import ( "errors" "io" diff --git a/vendor/github.com/shirou/gopsutil/v3/internal/common/common.go b/vendor/github.com/shirou/gopsutil/v3/internal/common/common.go index adc4922bd3..7a31d251b6 100644 --- a/vendor/github.com/shirou/gopsutil/v3/internal/common/common.go +++ b/vendor/github.com/shirou/gopsutil/v3/internal/common/common.go @@ -6,6 +6,7 @@ package common // - linux (amd64, arm) // - freebsd (amd64) // - windows (amd64) + import ( "bufio" "bytes" @@ -24,6 +25,8 @@ import ( "strconv" "strings" "time" + + "github.com/shirou/gopsutil/v3/common" ) var ( @@ -111,11 +114,35 @@ func ReadLines(filename string) ([]string, error) { return ReadLinesOffsetN(filename, 0, -1) } +// ReadLine reads a file and returns the first occurrence of a line that is prefixed with prefix. +func ReadLine(filename string, prefix string) (string, error) { + f, err := os.Open(filename) + if err != nil { + return "", err + } + defer f.Close() + r := bufio.NewReader(f) + for { + line, err := r.ReadString('\n') + if err != nil { + if err == io.EOF { + break + } + return "", err + } + if strings.HasPrefix(line, prefix) { + return line, nil + } + } + + return "", nil +} + // ReadLinesOffsetN reads contents from file and splits them by new line. // The offset tells at which line number to start. // The count determines the number of lines to read (starting from offset): -// n >= 0: at most n lines -// n < 0: whole file +// n >= 0: at most n lines +// n < 0: whole file func ReadLinesOffsetN(filename string, offset uint, n int) ([]string, error) { f, err := os.Open(filename) if err != nil { @@ -320,6 +347,23 @@ func PathExistsWithContents(filename string) bool { return info.Size() > 4 // at least 4 bytes } +// GetEnvWithContext retrieves the environment variable key. If it does not exist it returns the default. +// The context may optionally contain a map superseding os.EnvKey. +func GetEnvWithContext(ctx context.Context, key string, dfault string, combineWith ...string) string { + var value string + if env, ok := ctx.Value(common.EnvKey).(common.EnvMap); ok { + value = env[common.EnvKeyType(key)] + } + if value == "" { + value = os.Getenv(key) + } + if value == "" { + value = dfault + } + + return combine(value, combineWith) +} + // GetEnv retrieves the environment variable key. If it does not exist it returns the default. func GetEnv(key string, dfault string, combineWith ...string) string { value := os.Getenv(key) @@ -327,6 +371,10 @@ func GetEnv(key string, dfault string, combineWith ...string) string { value = dfault } + return combine(value, combineWith) +} + +func combine(value string, combineWith []string) string { switch len(combineWith) { case 0: return value @@ -364,14 +412,40 @@ func HostDev(combineWith ...string) string { return GetEnv("HOST_DEV", "/dev", combineWith...) } -// MockEnv set environment variable and return revert function. -// MockEnv should be used testing only. -func MockEnv(key string, value string) func() { - original := os.Getenv(key) - os.Setenv(key, value) - return func() { - os.Setenv(key, original) - } +func HostRoot(combineWith ...string) string { + return GetEnv("HOST_ROOT", "/", combineWith...) +} + +func HostProcWithContext(ctx context.Context, combineWith ...string) string { + return GetEnvWithContext(ctx, "HOST_PROC", "/proc", combineWith...) +} + +func HostProcMountInfoWithContext(ctx context.Context, combineWith ...string) string { + return GetEnvWithContext(ctx, "HOST_PROC_MOUNTINFO", "", combineWith...) +} + +func HostSysWithContext(ctx context.Context, combineWith ...string) string { + return GetEnvWithContext(ctx, "HOST_SYS", "/sys", combineWith...) +} + +func HostEtcWithContext(ctx context.Context, combineWith ...string) string { + return GetEnvWithContext(ctx, "HOST_ETC", "/etc", combineWith...) +} + +func HostVarWithContext(ctx context.Context, combineWith ...string) string { + return GetEnvWithContext(ctx, "HOST_VAR", "/var", combineWith...) +} + +func HostRunWithContext(ctx context.Context, combineWith ...string) string { + return GetEnvWithContext(ctx, "HOST_RUN", "/run", combineWith...) +} + +func HostDevWithContext(ctx context.Context, combineWith ...string) string { + return GetEnvWithContext(ctx, "HOST_DEV", "/dev", combineWith...) +} + +func HostRootWithContext(ctx context.Context, combineWith ...string) string { + return GetEnvWithContext(ctx, "HOST_ROOT", "/", combineWith...) } // getSysctrlEnv sets LC_ALL=C in a list of env vars for use when running diff --git a/vendor/github.com/shirou/gopsutil/v3/internal/common/common_linux.go b/vendor/github.com/shirou/gopsutil/v3/internal/common/common_linux.go index da44c3f2bc..a644687bac 100644 --- a/vendor/github.com/shirou/gopsutil/v3/internal/common/common_linux.go +++ b/vendor/github.com/shirou/gopsutil/v3/internal/common/common_linux.go @@ -12,6 +12,7 @@ import ( "strconv" "strings" "sync" + "syscall" "time" ) @@ -30,7 +31,11 @@ func DoSysctrl(mib string) ([]string, error) { } func NumProcs() (uint64, error) { - f, err := os.Open(HostProc()) + return NumProcsWithContext(context.Background()) +} + +func NumProcsWithContext(ctx context.Context) (uint64, error) { + f, err := os.Open(HostProcWithContext(ctx)) if err != nil { return 0, err } @@ -57,50 +62,70 @@ func BootTimeWithContext(ctx context.Context) (uint64, error) { return 0, err } - statFile := "stat" + useStatFile := true if system == "lxc" && role == "guest" { // if lxc, /proc/uptime is used. - statFile = "uptime" + useStatFile = false } else if system == "docker" && role == "guest" { // also docker, guest - statFile = "uptime" + useStatFile = false + } + + if useStatFile { + return readBootTimeStat(ctx) } - filename := HostProc(statFile) + filename := HostProcWithContext(ctx, "uptime") lines, err := ReadLines(filename) + if err != nil { + return handleBootTimeFileReadErr(err) + } + if len(lines) != 1 { + return 0, fmt.Errorf("wrong uptime format") + } + f := strings.Fields(lines[0]) + b, err := strconv.ParseFloat(f[0], 64) if err != nil { return 0, err } + currentTime := float64(time.Now().UnixNano()) / float64(time.Second) + t := currentTime - b + return uint64(t), nil +} - if statFile == "stat" { - for _, line := range lines { - if strings.HasPrefix(line, "btime") { - f := strings.Fields(line) - if len(f) != 2 { - return 0, fmt.Errorf("wrong btime format") - } - b, err := strconv.ParseInt(f[1], 10, 64) - if err != nil { - return 0, err - } - t := uint64(b) - return t, nil - } - } - } else if statFile == "uptime" { - if len(lines) != 1 { - return 0, fmt.Errorf("wrong uptime format") - } - f := strings.Fields(lines[0]) - b, err := strconv.ParseFloat(f[0], 64) +func handleBootTimeFileReadErr(err error) (uint64, error) { + if os.IsPermission(err) { + var info syscall.Sysinfo_t + err := syscall.Sysinfo(&info) if err != nil { return 0, err } - currentTime := float64(time.Now().UnixNano()) / float64(time.Second) - t := currentTime - b + + currentTime := time.Now().UnixNano() / int64(time.Second) + t := currentTime - int64(info.Uptime) return uint64(t), nil } + return 0, err +} +func readBootTimeStat(ctx context.Context) (uint64, error) { + filename := HostProcWithContext(ctx, "stat") + line, err := ReadLine(filename, "btime") + if err != nil { + return handleBootTimeFileReadErr(err) + } + if strings.HasPrefix(line, "btime") { + f := strings.Fields(line) + if len(f) != 2 { + return 0, fmt.Errorf("wrong btime format") + } + b, err := strconv.ParseInt(f[1], 10, 64) + if err != nil { + return 0, err + } + t := uint64(b) + return t, nil + } return 0, fmt.Errorf("could not find btime") } @@ -127,7 +152,7 @@ func VirtualizationWithContext(ctx context.Context) (string, string, error) { } cachedVirtMutex.RUnlock() - filename := HostProc("xen") + filename := HostProcWithContext(ctx, "xen") if PathExists(filename) { system = "xen" role = "guest" // assume guest @@ -142,13 +167,16 @@ func VirtualizationWithContext(ctx context.Context) (string, string, error) { } } - filename = HostProc("modules") + filename = HostProcWithContext(ctx, "modules") if PathExists(filename) { contents, err := ReadLines(filename) if err == nil { if StringsContains(contents, "kvm") { system = "kvm" role = "host" + } else if StringsContains(contents, "hv_util") { + system = "hyperv" + role = "guest" } else if StringsContains(contents, "vboxdrv") { system = "vbox" role = "host" @@ -162,7 +190,7 @@ func VirtualizationWithContext(ctx context.Context) (string, string, error) { } } - filename = HostProc("cpuinfo") + filename = HostProcWithContext(ctx, "cpuinfo") if PathExists(filename) { contents, err := ReadLines(filename) if err == nil { @@ -175,7 +203,7 @@ func VirtualizationWithContext(ctx context.Context) (string, string, error) { } } - filename = HostProc("bus/pci/devices") + filename = HostProcWithContext(ctx, "bus/pci/devices") if PathExists(filename) { contents, err := ReadLines(filename) if err == nil { @@ -185,7 +213,7 @@ func VirtualizationWithContext(ctx context.Context) (string, string, error) { } } - filename = HostProc() + filename = HostProcWithContext(ctx) if PathExists(filepath.Join(filename, "bc", "0")) { system = "openvz" role = "host" @@ -236,14 +264,19 @@ func VirtualizationWithContext(ctx context.Context) (string, string, error) { } } - if PathExists(HostEtc("os-release")) { - p, _, err := GetOSRelease() + if PathExists(HostEtcWithContext(ctx, "os-release")) { + p, _, err := GetOSReleaseWithContext(ctx) if err == nil && p == "coreos" { system = "rkt" // Is it true? role = "host" } } + if PathExists(HostRootWithContext(ctx, ".dockerenv")) { + system = "docker" + role = "guest" + } + // before returning for the first time, cache the system and role cachedVirtOnce.Do(func() { cachedVirtMutex.Lock() @@ -258,7 +291,11 @@ func VirtualizationWithContext(ctx context.Context) (string, string, error) { } func GetOSRelease() (platform string, version string, err error) { - contents, err := ReadLines(HostEtc("os-release")) + return GetOSReleaseWithContext(context.Background()) +} + +func GetOSReleaseWithContext(ctx context.Context) (platform string, version string, err error) { + contents, err := ReadLines(HostEtcWithContext(ctx, "os-release")) if err != nil { return "", "", nil // return empty } diff --git a/vendor/github.com/shirou/gopsutil/v3/internal/common/common_windows.go b/vendor/github.com/shirou/gopsutil/v3/internal/common/common_windows.go index 295b70bfae..301b2315bb 100644 --- a/vendor/github.com/shirou/gopsutil/v3/internal/common/common_windows.go +++ b/vendor/github.com/shirou/gopsutil/v3/internal/common/common_windows.go @@ -218,9 +218,12 @@ func WMIQueryWithContext(ctx context.Context, query string, dst interface{}, con } // Convert paths using native DOS format like: -// "\Device\HarddiskVolume1\Windows\systemew\file.txt" +// +// "\Device\HarddiskVolume1\Windows\systemew\file.txt" +// // into: -// "C:\Windows\systemew\file.txt" +// +// "C:\Windows\systemew\file.txt" func ConvertDOSPath(p string) string { rawDrive := strings.Join(strings.Split(p, `\`)[:3], `\`) diff --git a/vendor/github.com/shirou/gopsutil/v3/internal/common/sleep.go b/vendor/github.com/shirou/gopsutil/v3/internal/common/sleep.go index 8c35b17220..9bed2419ed 100644 --- a/vendor/github.com/shirou/gopsutil/v3/internal/common/sleep.go +++ b/vendor/github.com/shirou/gopsutil/v3/internal/common/sleep.go @@ -11,6 +11,9 @@ func Sleep(ctx context.Context, interval time.Duration) error { timer := time.NewTimer(interval) select { case <-ctx.Done(): + if !timer.Stop() { + <-timer.C + } return ctx.Err() case <-timer.C: return nil diff --git a/vendor/github.com/shirou/gopsutil/v3/internal/common/warnings.go b/vendor/github.com/shirou/gopsutil/v3/internal/common/warnings.go new file mode 100644 index 0000000000..a4aaadaf54 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/internal/common/warnings.go @@ -0,0 +1,30 @@ +package common + +import "fmt" + +type Warnings struct { + List []error + Verbose bool +} + +func (w *Warnings) Add(err error) { + w.List = append(w.List, err) +} + +func (w *Warnings) Reference() error { + if len(w.List) > 0 { + return w + } + return nil +} + +func (w *Warnings) Error() string { + if w.Verbose { + str := "" + for i, e := range w.List { + str += fmt.Sprintf("\tError %d: %s\n", i, e.Error()) + } + return str + } + return fmt.Sprintf("Number of warnings: %v", len(w.List)) +} diff --git a/vendor/github.com/shirou/gopsutil/v3/mem/mem_aix_nocgo.go b/vendor/github.com/shirou/gopsutil/v3/mem/mem_aix_nocgo.go index 09ffd8ed18..fc9e49222d 100644 --- a/vendor/github.com/shirou/gopsutil/v3/mem/mem_aix_nocgo.go +++ b/vendor/github.com/shirou/gopsutil/v3/mem/mem_aix_nocgo.go @@ -71,7 +71,7 @@ func callSVMon(ctx context.Context) (*VirtualMemoryStat, *SwapMemoryStat, error) swap.Total = t * pagesize } if t, err := strconv.ParseUint(p[3], 10, 64); err == nil { - swap.Free = swap.Total - t * pagesize + swap.Free = swap.Total - t*pagesize } } break diff --git a/vendor/github.com/shirou/gopsutil/v3/mem/mem_darwin.go b/vendor/github.com/shirou/gopsutil/v3/mem/mem_darwin.go index 0527dd93cb..a05a0faba0 100644 --- a/vendor/github.com/shirou/gopsutil/v3/mem/mem_darwin.go +++ b/vendor/github.com/shirou/gopsutil/v3/mem/mem_darwin.go @@ -8,8 +8,9 @@ import ( "fmt" "unsafe" - "github.com/shirou/gopsutil/v3/internal/common" "golang.org/x/sys/unix" + + "github.com/shirou/gopsutil/v3/internal/common" ) func getHwMemsize() (uint64, error) { diff --git a/vendor/github.com/shirou/gopsutil/v3/mem/mem_freebsd.go b/vendor/github.com/shirou/gopsutil/v3/mem/mem_freebsd.go index 44543ef746..9a56785b31 100644 --- a/vendor/github.com/shirou/gopsutil/v3/mem/mem_freebsd.go +++ b/vendor/github.com/shirou/gopsutil/v3/mem/mem_freebsd.go @@ -8,9 +8,8 @@ import ( "errors" "unsafe" - "golang.org/x/sys/unix" - "github.com/shirou/gopsutil/v3/internal/common" + "golang.org/x/sys/unix" ) func VirtualMemory() (*VirtualMemoryStat, error) { diff --git a/vendor/github.com/shirou/gopsutil/v3/mem/mem_linux.go b/vendor/github.com/shirou/gopsutil/v3/mem/mem_linux.go index 9a5d693b1d..9353317287 100644 --- a/vendor/github.com/shirou/gopsutil/v3/mem/mem_linux.go +++ b/vendor/github.com/shirou/gopsutil/v3/mem/mem_linux.go @@ -14,8 +14,9 @@ import ( "strconv" "strings" - "github.com/shirou/gopsutil/v3/internal/common" "golang.org/x/sys/unix" + + "github.com/shirou/gopsutil/v3/internal/common" ) type VirtualMemoryExStat struct { @@ -36,7 +37,7 @@ func VirtualMemory() (*VirtualMemoryStat, error) { } func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) { - vm, _, err := fillFromMeminfoWithContext() + vm, _, err := fillFromMeminfoWithContext(ctx) if err != nil { return nil, err } @@ -48,15 +49,15 @@ func VirtualMemoryEx() (*VirtualMemoryExStat, error) { } func VirtualMemoryExWithContext(ctx context.Context) (*VirtualMemoryExStat, error) { - _, vmEx, err := fillFromMeminfoWithContext() + _, vmEx, err := fillFromMeminfoWithContext(ctx) if err != nil { return nil, err } return vmEx, nil } -func fillFromMeminfoWithContext() (*VirtualMemoryStat, *VirtualMemoryExStat, error) { - filename := common.HostProc("meminfo") +func fillFromMeminfoWithContext(ctx context.Context) (*VirtualMemoryStat, *VirtualMemoryExStat, error) { + filename := common.HostProcWithContext(ctx, "meminfo") lines, _ := common.ReadLines(filename) // flag if MemAvailable is in /proc/meminfo (kernel 3.14+) @@ -153,13 +154,13 @@ func fillFromMeminfoWithContext() (*VirtualMemoryStat, *VirtualMemoryExStat, err return ret, retEx, err } retEx.Unevictable = t * 1024 - case "WriteBack": + case "Writeback": t, err := strconv.ParseUint(value, 10, 64) if err != nil { return ret, retEx, err } ret.WriteBack = t * 1024 - case "WriteBackTmp": + case "WritebackTmp": t, err := strconv.ParseUint(value, 10, 64) if err != nil { return ret, retEx, err @@ -317,7 +318,7 @@ func fillFromMeminfoWithContext() (*VirtualMemoryStat, *VirtualMemoryExStat, err if !memavail { if activeFile && inactiveFile && sReclaimable { - ret.Available = calculateAvailVmem(ret, retEx) + ret.Available = calculateAvailVmem(ctx, ret, retEx) } else { ret.Available = ret.Cached + ret.Free } @@ -350,7 +351,7 @@ func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) { } else { ret.UsedPercent = 0 } - filename := common.HostProc("vmstat") + filename := common.HostProcWithContext(ctx, "vmstat") lines, _ := common.ReadLines(filename) for _, l := range lines { fields := strings.Fields(l) @@ -370,25 +371,25 @@ func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) { continue } ret.Sout = value * 4 * 1024 - case "pgpgIn": + case "pgpgin": value, err := strconv.ParseUint(fields[1], 10, 64) if err != nil { continue } ret.PgIn = value * 4 * 1024 - case "pgpgOut": + case "pgpgout": value, err := strconv.ParseUint(fields[1], 10, 64) if err != nil { continue } ret.PgOut = value * 4 * 1024 - case "pgFault": + case "pgfault": value, err := strconv.ParseUint(fields[1], 10, 64) if err != nil { continue } ret.PgFault = value * 4 * 1024 - case "pgMajFault": + case "pgmajfault": value, err := strconv.ParseUint(fields[1], 10, 64) if err != nil { continue @@ -402,10 +403,10 @@ func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) { // calculateAvailVmem is a fallback under kernel 3.14 where /proc/meminfo does not provide // "MemAvailable:" column. It reimplements an algorithm from the link below // https://github.com/giampaolo/psutil/pull/890 -func calculateAvailVmem(ret *VirtualMemoryStat, retEx *VirtualMemoryExStat) uint64 { +func calculateAvailVmem(ctx context.Context, ret *VirtualMemoryStat, retEx *VirtualMemoryExStat) uint64 { var watermarkLow uint64 - fn := common.HostProc("zoneinfo") + fn := common.HostProcWithContext(ctx, "zoneinfo") lines, err := common.ReadLines(fn) if err != nil { return ret.Free + ret.Cached // fallback under kernel 2.6.13 @@ -457,18 +458,18 @@ func SwapDevices() ([]*SwapDevice, error) { } func SwapDevicesWithContext(ctx context.Context) ([]*SwapDevice, error) { - swapsFilePath := common.HostProc(swapsFilename) + swapsFilePath := common.HostProcWithContext(ctx, swapsFilename) f, err := os.Open(swapsFilePath) if err != nil { return nil, err } defer f.Close() - return parseSwapsFile(f) + return parseSwapsFile(ctx, f) } -func parseSwapsFile(r io.Reader) ([]*SwapDevice, error) { - swapsFilePath := common.HostProc(swapsFilename) +func parseSwapsFile(ctx context.Context, r io.Reader) ([]*SwapDevice, error) { + swapsFilePath := common.HostProcWithContext(ctx, swapsFilename) scanner := bufio.NewScanner(r) if !scanner.Scan() { if err := scanner.Err(); err != nil { diff --git a/vendor/github.com/shirou/gopsutil/v3/mem/mem_openbsd.go b/vendor/github.com/shirou/gopsutil/v3/mem/mem_openbsd.go index 97644923af..e37d5abe0d 100644 --- a/vendor/github.com/shirou/gopsutil/v3/mem/mem_openbsd.go +++ b/vendor/github.com/shirou/gopsutil/v3/mem/mem_openbsd.go @@ -9,6 +9,7 @@ import ( "encoding/binary" "errors" "fmt" + "github.com/shirou/gopsutil/v3/internal/common" "golang.org/x/sys/unix" ) diff --git a/vendor/github.com/shirou/gopsutil/v3/mem/mem_solaris.go b/vendor/github.com/shirou/gopsutil/v3/mem/mem_solaris.go index 88f05f65df..c911267e1e 100644 --- a/vendor/github.com/shirou/gopsutil/v3/mem/mem_solaris.go +++ b/vendor/github.com/shirou/gopsutil/v3/mem/mem_solaris.go @@ -12,6 +12,7 @@ import ( "strings" "github.com/shirou/gopsutil/v3/internal/common" + "github.com/tklauser/go-sysconf" ) // VirtualMemory for Solaris is a minimal implementation which only returns @@ -34,6 +35,13 @@ func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) { return nil, err } result.Total = cap + freemem, err := globalZoneFreeMemory(ctx) + if err != nil { + return nil, err + } + result.Available = freemem + result.Free = freemem + result.Used = result.Total - result.Free } else { cap, err := nonGlobalZoneMemoryCapacity() if err != nil { @@ -85,6 +93,25 @@ func globalZoneMemoryCapacity() (uint64, error) { return totalMB * 1024 * 1024, nil } +func globalZoneFreeMemory(ctx context.Context) (uint64, error) { + output, err := invoke.CommandWithContext(ctx, "pagesize") + if err != nil { + return 0, err + } + + pagesize, err := strconv.ParseUint(strings.TrimSpace(string(output)), 10, 64) + if err != nil { + return 0, err + } + + free, err := sysconf.Sysconf(sysconf.SC_AVPHYS_PAGES) + if err != nil { + return 0, err + } + + return uint64(free) * pagesize, nil +} + var kstatMatch = regexp.MustCompile(`(\S+)\s+(\S*)`) func nonGlobalZoneMemoryCapacity() (uint64, error) { diff --git a/vendor/github.com/shirou/gopsutil/v3/net/net_aix_cgo.go b/vendor/github.com/shirou/gopsutil/v3/net/net_aix_cgo.go index 8cf8c91424..8c34f881c0 100644 --- a/vendor/github.com/shirou/gopsutil/v3/net/net_aix_cgo.go +++ b/vendor/github.com/shirou/gopsutil/v3/net/net_aix_cgo.go @@ -18,14 +18,14 @@ func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, iocounters := make([]IOCountersStat, 0, len(ifs)) for _, netif := range ifs { n := IOCountersStat{ - Name: netif.Name, - BytesSent: uint64(netif.OBytes), - BytesRecv: uint64(netif.IBytes), + Name: netif.Name, + BytesSent: uint64(netif.OBytes), + BytesRecv: uint64(netif.IBytes), PacketsSent: uint64(netif.OPackets), PacketsRecv: uint64(netif.IPackets), - Errin: uint64(netif.OErrors), - Errout: uint64(netif.IErrors), - Dropout: uint64(netif.XmitDrops), + Errin: uint64(netif.OErrors), + Errout: uint64(netif.IErrors), + Dropout: uint64(netif.XmitDrops), } iocounters = append(iocounters, n) } diff --git a/vendor/github.com/shirou/gopsutil/v3/net/net_darwin.go b/vendor/github.com/shirou/gopsutil/v3/net/net_darwin.go index 1c8d4f4e35..8a7b637443 100644 --- a/vendor/github.com/shirou/gopsutil/v3/net/net_darwin.go +++ b/vendor/github.com/shirou/gopsutil/v3/net/net_darwin.go @@ -259,7 +259,7 @@ func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) { } func IOCountersByFileWithContext(ctx context.Context, pernic bool, filename string) ([]IOCountersStat, error) { - return IOCounters(pernic) + return IOCountersWithContext(ctx, pernic) } func FilterCounters() ([]FilterStat, error) { @@ -278,7 +278,7 @@ func ConntrackStatsWithContext(ctx context.Context, percpu bool) ([]ConntrackSta return nil, common.ErrNotImplementedError } -// NetProtoCounters returns network statistics for the entire system +// ProtoCounters returns network statistics for the entire system // If protocols is empty then all protocols are returned, otherwise // just the protocols in the list are returned. // Not Implemented for Darwin diff --git a/vendor/github.com/shirou/gopsutil/v3/net/net_fallback.go b/vendor/github.com/shirou/gopsutil/v3/net/net_fallback.go index 58325f655f..e136be1bac 100644 --- a/vendor/github.com/shirou/gopsutil/v3/net/net_fallback.go +++ b/vendor/github.com/shirou/gopsutil/v3/net/net_fallback.go @@ -1,5 +1,5 @@ -//go:build !aix && !darwin && !linux && !freebsd && !openbsd && !windows -// +build !aix,!darwin,!linux,!freebsd,!openbsd,!windows +//go:build !aix && !darwin && !linux && !freebsd && !openbsd && !windows && !solaris +// +build !aix,!darwin,!linux,!freebsd,!openbsd,!windows,!solaris package net diff --git a/vendor/github.com/shirou/gopsutil/v3/net/net_freebsd.go b/vendor/github.com/shirou/gopsutil/v3/net/net_freebsd.go index 7f31851ea2..bf8baf0949 100644 --- a/vendor/github.com/shirou/gopsutil/v3/net/net_freebsd.go +++ b/vendor/github.com/shirou/gopsutil/v3/net/net_freebsd.go @@ -115,7 +115,7 @@ func ConntrackStatsWithContext(ctx context.Context, percpu bool) ([]ConntrackSta return nil, common.ErrNotImplementedError } -// NetProtoCounters returns network statistics for the entire system +// ProtoCounters returns network statistics for the entire system // If protocols is empty then all protocols are returned, otherwise // just the protocols in the list are returned. // Not Implemented for FreeBSD diff --git a/vendor/github.com/shirou/gopsutil/v3/net/net_linux.go b/vendor/github.com/shirou/gopsutil/v3/net/net_linux.go index c089971966..de0ea73452 100644 --- a/vendor/github.com/shirou/gopsutil/v3/net/net_linux.go +++ b/vendor/github.com/shirou/gopsutil/v3/net/net_linux.go @@ -50,7 +50,7 @@ func IOCounters(pernic bool) ([]IOCountersStat, error) { } func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, error) { - filename := common.HostProc("net/dev") + filename := common.HostProcWithContext(ctx, "net/dev") return IOCountersByFileWithContext(ctx, pernic, filename) } @@ -157,11 +157,11 @@ var netProtocols = []string{ "udplite", } -// NetProtoCounters returns network statistics for the entire system +// ProtoCounters returns network statistics for the entire system // If protocols is empty then all protocols are returned, otherwise // just the protocols in the list are returned. // Available protocols: -// ip,icmp,icmpmsg,tcp,udp,udplite +// [ip,icmp,icmpmsg,tcp,udp,udplite] func ProtoCounters(protocols []string) ([]ProtoCountersStat, error) { return ProtoCountersWithContext(context.Background(), protocols) } @@ -177,7 +177,7 @@ func ProtoCountersWithContext(ctx context.Context, protocols []string) ([]ProtoC protos[p] = true } - filename := common.HostProc("net/snmp") + filename := common.HostProcWithContext(ctx, "net/snmp") lines, err := common.ReadLines(filename) if err != nil { return nil, err @@ -230,8 +230,8 @@ func FilterCounters() ([]FilterStat, error) { } func FilterCountersWithContext(ctx context.Context) ([]FilterStat, error) { - countfile := common.HostProc("sys/net/netfilter/nf_conntrack_count") - maxfile := common.HostProc("sys/net/netfilter/nf_conntrack_max") + countfile := common.HostProcWithContext(ctx, "sys/net/netfilter/nf_conntrack_count") + maxfile := common.HostProcWithContext(ctx, "sys/net/netfilter/nf_conntrack_max") count, err := common.ReadInts(countfile) if err != nil { @@ -260,7 +260,7 @@ func ConntrackStats(percpu bool) ([]ConntrackStat, error) { // ConntrackStatsWithContext returns more detailed info about the conntrack table func ConntrackStatsWithContext(ctx context.Context, percpu bool) ([]ConntrackStat, error) { - return conntrackStatsFromFile(common.HostProc("net/stat/nf_conntrack"), percpu) + return conntrackStatsFromFile(common.HostProcWithContext(ctx, "net/stat/nf_conntrack"), percpu) } // conntrackStatsFromFile returns more detailed info about the conntrack table @@ -459,7 +459,7 @@ func connectionsPidMaxWithoutUidsWithContext(ctx context.Context, kind string, p if !ok { return nil, fmt.Errorf("invalid kind, %s", kind) } - root := common.HostProc() + root := common.HostProcWithContext(ctx) var err error var inodes map[string][]inodeMap if pid == 0 { @@ -531,7 +531,7 @@ func statsFromInodesWithContext(ctx context.Context, root string, pid int32, tma if !skipUids { // fetch process owner Real, effective, saved set, and filesystem UIDs proc := process{Pid: conn.Pid} - conn.Uids, _ = proc.getUids() + conn.Uids, _ = proc.getUids(ctx) } ret = append(ret, conn) @@ -599,7 +599,7 @@ func Pids() ([]int32, error) { func PidsWithContext(ctx context.Context) ([]int32, error) { var ret []int32 - d, err := os.Open(common.HostProc()) + d, err := os.Open(common.HostProcWithContext(ctx)) if err != nil { return nil, err } @@ -631,8 +631,8 @@ type process struct { } // Uids returns user ids of the process as a slice of the int -func (p *process) getUids() ([]int32, error) { - err := p.fillFromStatus() +func (p *process) getUids(ctx context.Context) ([]int32, error) { + err := p.fillFromStatus(ctx) if err != nil { return []int32{}, err } @@ -640,9 +640,9 @@ func (p *process) getUids() ([]int32, error) { } // Get status from /proc/(pid)/status -func (p *process) fillFromStatus() error { +func (p *process) fillFromStatus(ctx context.Context) error { pid := p.Pid - statPath := common.HostProc(strconv.Itoa(int(pid)), "status") + statPath := common.HostProcWithContext(ctx, strconv.Itoa(int(pid)), "status") contents, err := ioutil.ReadFile(statPath) if err != nil { return err diff --git a/vendor/github.com/shirou/gopsutil/v3/net/net_openbsd.go b/vendor/github.com/shirou/gopsutil/v3/net/net_openbsd.go index 5f066a09fb..cf48f53e75 100644 --- a/vendor/github.com/shirou/gopsutil/v3/net/net_openbsd.go +++ b/vendor/github.com/shirou/gopsutil/v3/net/net_openbsd.go @@ -164,7 +164,7 @@ func ConntrackStatsWithContext(ctx context.Context, percpu bool) ([]ConntrackSta return nil, common.ErrNotImplementedError } -// NetProtoCounters returns network statistics for the entire system +// ProtoCounters returns network statistics for the entire system // If protocols is empty then all protocols are returned, otherwise // just the protocols in the list are returned. // Not Implemented for OpenBSD diff --git a/vendor/github.com/shirou/gopsutil/v3/net/net_solaris.go b/vendor/github.com/shirou/gopsutil/v3/net/net_solaris.go new file mode 100644 index 0000000000..7f1f5c86fe --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/v3/net/net_solaris.go @@ -0,0 +1,143 @@ +//go:build solaris +// +build solaris + +package net + +import ( + "context" + "fmt" + "regexp" + "runtime" + "strconv" + "strings" + + "github.com/shirou/gopsutil/v3/internal/common" +) + +// NetIOCounters returnes network I/O statistics for every network +// interface installed on the system. If pernic argument is false, +// return only sum of all information (which name is 'all'). If true, +// every network interface installed on the system is returned +// separately. +func IOCounters(pernic bool) ([]IOCountersStat, error) { + return IOCountersWithContext(context.Background(), pernic) +} + +func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, error) { + // collect all the net class's links with below statistics + filterstr := "/^(?!vnic)/::phys:/^rbytes64$|^ipackets64$|^idrops64$|^ierrors$|^obytes64$|^opackets64$|^odrops64$|^oerrors$/" + if runtime.GOOS == "illumos" { + filterstr = "/[^vnic]/::mac:/^rbytes64$|^ipackets64$|^idrops64$|^ierrors$|^obytes64$|^opackets64$|^odrops64$|^oerrors$/" + } + kstatSysOut, err := invoke.CommandWithContext(ctx, "kstat", "-c", "net", "-p", filterstr) + if err != nil { + return nil, fmt.Errorf("cannot execute kstat: %w", err) + } + + lines := strings.Split(strings.TrimSpace(string(kstatSysOut)), "\n") + if len(lines) == 0 { + return nil, fmt.Errorf("no interface found") + } + rbytes64arr := make(map[string]uint64) + ipackets64arr := make(map[string]uint64) + idrops64arr := make(map[string]uint64) + ierrorsarr := make(map[string]uint64) + obytes64arr := make(map[string]uint64) + opackets64arr := make(map[string]uint64) + odrops64arr := make(map[string]uint64) + oerrorsarr := make(map[string]uint64) + + re := regexp.MustCompile(`[:\s]+`) + for _, line := range lines { + fields := re.Split(line, -1) + interfaceName := fields[0] + instance := fields[1] + switch fields[3] { + case "rbytes64": + rbytes64arr[interfaceName+instance], err = strconv.ParseUint(fields[4], 10, 64) + if err != nil { + return nil, fmt.Errorf("cannot parse rbytes64: %w", err) + } + case "ipackets64": + ipackets64arr[interfaceName+instance], err = strconv.ParseUint(fields[4], 10, 64) + if err != nil { + return nil, fmt.Errorf("cannot parse ipackets64: %w", err) + } + case "idrops64": + idrops64arr[interfaceName+instance], err = strconv.ParseUint(fields[4], 10, 64) + if err != nil { + return nil, fmt.Errorf("cannot parse idrops64: %w", err) + } + case "ierrors": + ierrorsarr[interfaceName+instance], err = strconv.ParseUint(fields[4], 10, 64) + if err != nil { + return nil, fmt.Errorf("cannot parse ierrors: %w", err) + } + case "obytes64": + obytes64arr[interfaceName+instance], err = strconv.ParseUint(fields[4], 10, 64) + if err != nil { + return nil, fmt.Errorf("cannot parse obytes64: %w", err) + } + case "opackets64": + opackets64arr[interfaceName+instance], err = strconv.ParseUint(fields[4], 10, 64) + if err != nil { + return nil, fmt.Errorf("cannot parse opackets64: %w", err) + } + case "odrops64": + odrops64arr[interfaceName+instance], err = strconv.ParseUint(fields[4], 10, 64) + if err != nil { + return nil, fmt.Errorf("cannot parse odrops64: %w", err) + } + case "oerrors": + oerrorsarr[interfaceName+instance], err = strconv.ParseUint(fields[4], 10, 64) + if err != nil { + return nil, fmt.Errorf("cannot parse oerrors: %w", err) + } + } + } + ret := make([]IOCountersStat, 0) + for k := range rbytes64arr { + nic := IOCountersStat{ + Name: k, + BytesRecv: rbytes64arr[k], + PacketsRecv: ipackets64arr[k], + Errin: ierrorsarr[k], + Dropin: idrops64arr[k], + BytesSent: obytes64arr[k], + PacketsSent: opackets64arr[k], + Errout: oerrorsarr[k], + Dropout: odrops64arr[k], + } + ret = append(ret, nic) + } + + if !pernic { + return getIOCountersAll(ret) + } + + return ret, nil +} + +func Connections(kind string) ([]ConnectionStat, error) { + return ConnectionsWithContext(context.Background(), kind) +} + +func ConnectionsWithContext(ctx context.Context, kind string) ([]ConnectionStat, error) { + return []ConnectionStat{}, common.ErrNotImplementedError +} + +func FilterCounters() ([]FilterStat, error) { + return FilterCountersWithContext(context.Background()) +} + +func FilterCountersWithContext(ctx context.Context) ([]FilterStat, error) { + return []FilterStat{}, common.ErrNotImplementedError +} + +func ProtoCounters(protocols []string) ([]ProtoCountersStat, error) { + return ProtoCountersWithContext(context.Background(), protocols) +} + +func ProtoCountersWithContext(ctx context.Context, protocols []string) ([]ProtoCountersStat, error) { + return []ProtoCountersStat{}, common.ErrNotImplementedError +} diff --git a/vendor/github.com/shirou/gopsutil/v3/net/net_unix.go b/vendor/github.com/shirou/gopsutil/v3/net/net_unix.go index 2fd2224fa3..cb846e28a6 100644 --- a/vendor/github.com/shirou/gopsutil/v3/net/net_unix.go +++ b/vendor/github.com/shirou/gopsutil/v3/net/net_unix.go @@ -20,7 +20,7 @@ func Connections(kind string) ([]ConnectionStat, error) { } func ConnectionsWithContext(ctx context.Context, kind string) ([]ConnectionStat, error) { - return ConnectionsPid(kind, 0) + return ConnectionsPidWithContext(ctx, kind, 0) } // Return a list of network connections opened returning at most `max` diff --git a/vendor/github.com/shirou/gopsutil/v3/net/net_windows.go b/vendor/github.com/shirou/gopsutil/v3/net/net_windows.go index 731c8f97bb..5d384342f8 100644 --- a/vendor/github.com/shirou/gopsutil/v3/net/net_windows.go +++ b/vendor/github.com/shirou/gopsutil/v3/net/net_windows.go @@ -211,7 +211,8 @@ func IOCountersByFileWithContext(ctx context.Context, pernic bool, filename stri // Return a list of network connections // Available kind: -// reference to netConnectionKindMap +// +// reference to netConnectionKindMap func Connections(kind string) ([]ConnectionStat, error) { return ConnectionsWithContext(context.Background(), kind) } @@ -337,7 +338,7 @@ func ConntrackStatsWithContext(ctx context.Context, percpu bool) ([]ConntrackSta return nil, common.ErrNotImplementedError } -// NetProtoCounters returns network statistics for the entire system +// ProtoCounters returns network statistics for the entire system // If protocols is empty then all protocols are returned, otherwise // just the protocols in the list are returned. // Not Implemented for Windows diff --git a/vendor/github.com/shirou/gopsutil/v3/process/process.go b/vendor/github.com/shirou/gopsutil/v3/process/process.go index 0ca26c2109..1a7fe1b80b 100644 --- a/vendor/github.com/shirou/gopsutil/v3/process/process.go +++ b/vendor/github.com/shirou/gopsutil/v3/process/process.go @@ -335,7 +335,7 @@ func (p *Process) MemoryPercentWithContext(ctx context.Context) (float32, error) return (100 * float32(used) / float32(total)), nil } -// CPU_Percent returns how many percent of the CPU time this process uses +// CPUPercent returns how many percent of the CPU time this process uses func (p *Process) CPUPercent() (float64, error) { return p.CPUPercentWithContext(context.Background()) } @@ -507,7 +507,7 @@ func (p *Process) MemoryInfoEx() (*MemoryInfoExStat, error) { return p.MemoryInfoExWithContext(context.Background()) } -// PageFaultsInfo returns the process's page fault counters. +// PageFaults returns the process's page fault counters. func (p *Process) PageFaults() (*PageFaultsStat, error) { return p.PageFaultsWithContext(context.Background()) } @@ -530,7 +530,7 @@ func (p *Process) Connections() ([]net.ConnectionStat, error) { return p.ConnectionsWithContext(context.Background()) } -// Connections returns a slice of net.ConnectionStat used by the process at most `max`. +// ConnectionsMax returns a slice of net.ConnectionStat used by the process at most `max`. func (p *Process) ConnectionsMax(max int) ([]net.ConnectionStat, error) { return p.ConnectionsMaxWithContext(context.Background(), max) } diff --git a/vendor/github.com/shirou/gopsutil/v3/process/process_darwin.go b/vendor/github.com/shirou/gopsutil/v3/process/process_darwin.go index 61b340b63f..176661cbd6 100644 --- a/vendor/github.com/shirou/gopsutil/v3/process/process_darwin.go +++ b/vendor/github.com/shirou/gopsutil/v3/process/process_darwin.go @@ -10,10 +10,11 @@ import ( "strconv" "strings" - "github.com/shirou/gopsutil/v3/internal/common" - "github.com/shirou/gopsutil/v3/net" "github.com/tklauser/go-sysconf" "golang.org/x/sys/unix" + + "github.com/shirou/gopsutil/v3/internal/common" + "github.com/shirou/gopsutil/v3/net" ) // copied from sys/sysctl.h @@ -81,8 +82,6 @@ func (p *Process) NameWithContext(ctx context.Context) (string, error) { extendedName := filepath.Base(cmdName) if strings.HasPrefix(extendedName, p.name) { name = extendedName - } else { - name = cmdName } } } diff --git a/vendor/github.com/shirou/gopsutil/v3/process/process_darwin_cgo.go b/vendor/github.com/shirou/gopsutil/v3/process/process_darwin_cgo.go index 2ac413f108..858f08e7a4 100644 --- a/vendor/github.com/shirou/gopsutil/v3/process/process_darwin_cgo.go +++ b/vendor/github.com/shirou/gopsutil/v3/process/process_darwin_cgo.go @@ -175,6 +175,7 @@ func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) { func (p *Process) NumThreadsWithContext(ctx context.Context) (int32, error) { const tiSize = C.sizeof_struct_proc_taskinfo ti := (*C.struct_proc_taskinfo)(C.malloc(tiSize)) + defer C.free(unsafe.Pointer(ti)) _, err := C.proc_pidinfo(C.int(p.Pid), C.PROC_PIDTASKINFO, 0, unsafe.Pointer(ti), tiSize) if err != nil { @@ -187,6 +188,7 @@ func (p *Process) NumThreadsWithContext(ctx context.Context) (int32, error) { func (p *Process) TimesWithContext(ctx context.Context) (*cpu.TimesStat, error) { const tiSize = C.sizeof_struct_proc_taskinfo ti := (*C.struct_proc_taskinfo)(C.malloc(tiSize)) + defer C.free(unsafe.Pointer(ti)) _, err := C.proc_pidinfo(C.int(p.Pid), C.PROC_PIDTASKINFO, 0, unsafe.Pointer(ti), tiSize) if err != nil { @@ -204,6 +206,7 @@ func (p *Process) TimesWithContext(ctx context.Context) (*cpu.TimesStat, error) func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, error) { const tiSize = C.sizeof_struct_proc_taskinfo ti := (*C.struct_proc_taskinfo)(C.malloc(tiSize)) + defer C.free(unsafe.Pointer(ti)) _, err := C.proc_pidinfo(C.int(p.Pid), C.PROC_PIDTASKINFO, 0, unsafe.Pointer(ti), tiSize) if err != nil { diff --git a/vendor/github.com/shirou/gopsutil/v3/process/process_freebsd.go b/vendor/github.com/shirou/gopsutil/v3/process/process_freebsd.go index 779f8126a9..85134b7ee6 100644 --- a/vendor/github.com/shirou/gopsutil/v3/process/process_freebsd.go +++ b/vendor/github.com/shirou/gopsutil/v3/process/process_freebsd.go @@ -55,8 +55,6 @@ func (p *Process) NameWithContext(ctx context.Context) (string, error) { extendedName := filepath.Base(cmdlineSlice[0]) if strings.HasPrefix(extendedName, p.name) { name = extendedName - } else { - name = cmdlineSlice[0] } } } @@ -69,7 +67,13 @@ func (p *Process) CwdWithContext(ctx context.Context) (string, error) { } func (p *Process) ExeWithContext(ctx context.Context) (string, error) { - return "", common.ErrNotImplementedError + mib := []int32{CTLKern, KernProc, KernProcPathname, p.Pid} + buf, _, err := common.CallSyscall(mib) + if err != nil { + return "", err + } + + return strings.Trim(string(buf), "\x00"), nil } func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) { diff --git a/vendor/github.com/shirou/gopsutil/v3/process/process_linux.go b/vendor/github.com/shirou/gopsutil/v3/process/process_linux.go index d5b5bc3294..37cb7ca44b 100644 --- a/vendor/github.com/shirou/gopsutil/v3/process/process_linux.go +++ b/vendor/github.com/shirou/gopsutil/v3/process/process_linux.go @@ -16,11 +16,12 @@ import ( "strconv" "strings" + "github.com/tklauser/go-sysconf" + "golang.org/x/sys/unix" + "github.com/shirou/gopsutil/v3/cpu" "github.com/shirou/gopsutil/v3/internal/common" "github.com/shirou/gopsutil/v3/net" - "github.com/tklauser/go-sysconf" - "golang.org/x/sys/unix" ) var pageSize = uint64(os.Getpagesize()) @@ -100,7 +101,7 @@ func (p *Process) TgidWithContext(ctx context.Context) (int32, error) { } func (p *Process) ExeWithContext(ctx context.Context) (string, error) { - return p.fillFromExeWithContext() + return p.fillFromExeWithContext(ctx) } func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) { @@ -120,7 +121,7 @@ func (p *Process) createTimeWithContext(ctx context.Context) (int64, error) { } func (p *Process) CwdWithContext(ctx context.Context) (string, error) { - return p.fillFromCwdWithContext() + return p.fillFromCwdWithContext(ctx) } func (p *Process) StatusWithContext(ctx context.Context) ([]string, error) { @@ -134,7 +135,7 @@ func (p *Process) StatusWithContext(ctx context.Context) ([]string, error) { func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) { // see https://github.com/shirou/gopsutil/issues/596#issuecomment-432707831 for implementation details pid := p.Pid - statPath := common.HostProc(strconv.Itoa(int(pid)), "stat") + statPath := common.HostProcWithContext(ctx, strconv.Itoa(int(pid)), "stat") contents, err := ioutil.ReadFile(statPath) if err != nil { return false, err @@ -202,7 +203,7 @@ func (p *Process) RlimitWithContext(ctx context.Context) ([]RlimitStat, error) { } func (p *Process) RlimitUsageWithContext(ctx context.Context, gatherUsed bool) ([]RlimitStat, error) { - rlimits, err := p.fillFromLimitsWithContext() + rlimits, err := p.fillFromLimitsWithContext(ctx) if !gatherUsed || err != nil { return rlimits, err } @@ -257,7 +258,7 @@ func (p *Process) RlimitUsageWithContext(ctx context.Context, gatherUsed bool) ( } func (p *Process) IOCountersWithContext(ctx context.Context) (*IOCountersStat, error) { - return p.fillFromIOWithContext() + return p.fillFromIOWithContext(ctx) } func (p *Process) NumCtxSwitchesWithContext(ctx context.Context) (*NumCtxSwitchesStat, error) { @@ -283,7 +284,7 @@ func (p *Process) NumThreadsWithContext(ctx context.Context) (int32, error) { func (p *Process) ThreadsWithContext(ctx context.Context) (map[int32]*cpu.TimesStat, error) { ret := make(map[int32]*cpu.TimesStat) - taskPath := common.HostProc(strconv.Itoa(int(p.Pid)), "task") + taskPath := common.HostProcWithContext(ctx, strconv.Itoa(int(p.Pid)), "task") tids, err := readPidsFromDir(taskPath) if err != nil { @@ -314,7 +315,7 @@ func (p *Process) CPUAffinityWithContext(ctx context.Context) ([]int32, error) { } func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, error) { - meminfo, _, err := p.fillFromStatmWithContext() + meminfo, _, err := p.fillFromStatmWithContext(ctx) if err != nil { return nil, err } @@ -322,7 +323,7 @@ func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, e } func (p *Process) MemoryInfoExWithContext(ctx context.Context) (*MemoryInfoExStat, error) { - _, memInfoEx, err := p.fillFromStatmWithContext() + _, memInfoEx, err := p.fillFromStatmWithContext(ctx) if err != nil { return nil, err } @@ -380,12 +381,12 @@ func (p *Process) ConnectionsMaxWithContext(ctx context.Context, max int) ([]net func (p *Process) MemoryMapsWithContext(ctx context.Context, grouped bool) (*[]MemoryMapsStat, error) { pid := p.Pid var ret []MemoryMapsStat - smapsPath := common.HostProc(strconv.Itoa(int(pid)), "smaps") + smapsPath := common.HostProcWithContext(ctx, strconv.Itoa(int(pid)), "smaps") if grouped { ret = make([]MemoryMapsStat, 1) // If smaps_rollup exists (require kernel >= 4.15), then we will use it // for pre-summed memory information for a process. - smapsRollupPath := common.HostProc(strconv.Itoa(int(pid)), "smaps_rollup") + smapsRollupPath := common.HostProcWithContext(ctx, strconv.Itoa(int(pid)), "smaps_rollup") if _, err := os.Stat(smapsRollupPath); !os.IsNotExist(err) { smapsPath = smapsRollupPath } @@ -481,7 +482,7 @@ func (p *Process) MemoryMapsWithContext(ctx context.Context, grouped bool) (*[]M } func (p *Process) EnvironWithContext(ctx context.Context) ([]string, error) { - environPath := common.HostProc(strconv.Itoa(int(p.Pid)), "environ") + environPath := common.HostProcWithContext(ctx, strconv.Itoa(int(p.Pid)), "environ") environContent, err := ioutil.ReadFile(environPath) if err != nil { @@ -507,9 +508,9 @@ func limitToUint(val string) (uint64, error) { } // Get num_fds from /proc/(pid)/limits -func (p *Process) fillFromLimitsWithContext() ([]RlimitStat, error) { +func (p *Process) fillFromLimitsWithContext(ctx context.Context) ([]RlimitStat, error) { pid := p.Pid - limitsFile := common.HostProc(strconv.Itoa(int(pid)), "limits") + limitsFile := common.HostProcWithContext(ctx, strconv.Itoa(int(pid)), "limits") d, err := os.Open(limitsFile) if err != nil { return nil, err @@ -602,7 +603,7 @@ func (p *Process) fillFromLimitsWithContext() ([]RlimitStat, error) { // Get list of /proc/(pid)/fd files func (p *Process) fillFromfdListWithContext(ctx context.Context) (string, []string, error) { pid := p.Pid - statPath := common.HostProc(strconv.Itoa(int(pid)), "fd") + statPath := common.HostProcWithContext(ctx, strconv.Itoa(int(pid)), "fd") d, err := os.Open(statPath) if err != nil { return statPath, []string{}, err @@ -642,9 +643,9 @@ func (p *Process) fillFromfdWithContext(ctx context.Context) (int32, []*OpenFile } // Get cwd from /proc/(pid)/cwd -func (p *Process) fillFromCwdWithContext() (string, error) { +func (p *Process) fillFromCwdWithContext(ctx context.Context) (string, error) { pid := p.Pid - cwdPath := common.HostProc(strconv.Itoa(int(pid)), "cwd") + cwdPath := common.HostProcWithContext(ctx, strconv.Itoa(int(pid)), "cwd") cwd, err := os.Readlink(cwdPath) if err != nil { return "", err @@ -653,9 +654,9 @@ func (p *Process) fillFromCwdWithContext() (string, error) { } // Get exe from /proc/(pid)/exe -func (p *Process) fillFromExeWithContext() (string, error) { +func (p *Process) fillFromExeWithContext(ctx context.Context) (string, error) { pid := p.Pid - exePath := common.HostProc(strconv.Itoa(int(pid)), "exe") + exePath := common.HostProcWithContext(ctx, strconv.Itoa(int(pid)), "exe") exe, err := os.Readlink(exePath) if err != nil { return "", err @@ -666,7 +667,7 @@ func (p *Process) fillFromExeWithContext() (string, error) { // Get cmdline from /proc/(pid)/cmdline func (p *Process) fillFromCmdlineWithContext(ctx context.Context) (string, error) { pid := p.Pid - cmdPath := common.HostProc(strconv.Itoa(int(pid)), "cmdline") + cmdPath := common.HostProcWithContext(ctx, strconv.Itoa(int(pid)), "cmdline") cmdline, err := ioutil.ReadFile(cmdPath) if err != nil { return "", err @@ -680,7 +681,7 @@ func (p *Process) fillFromCmdlineWithContext(ctx context.Context) (string, error func (p *Process) fillSliceFromCmdlineWithContext(ctx context.Context) ([]string, error) { pid := p.Pid - cmdPath := common.HostProc(strconv.Itoa(int(pid)), "cmdline") + cmdPath := common.HostProcWithContext(ctx, strconv.Itoa(int(pid)), "cmdline") cmdline, err := ioutil.ReadFile(cmdPath) if err != nil { return nil, err @@ -701,9 +702,9 @@ func (p *Process) fillSliceFromCmdlineWithContext(ctx context.Context) ([]string } // Get IO status from /proc/(pid)/io -func (p *Process) fillFromIOWithContext() (*IOCountersStat, error) { +func (p *Process) fillFromIOWithContext(ctx context.Context) (*IOCountersStat, error) { pid := p.Pid - ioPath := common.HostProc(strconv.Itoa(int(pid)), "io") + ioPath := common.HostProcWithContext(ctx, strconv.Itoa(int(pid)), "io") ioline, err := ioutil.ReadFile(ioPath) if err != nil { return nil, err @@ -737,9 +738,9 @@ func (p *Process) fillFromIOWithContext() (*IOCountersStat, error) { } // Get memory info from /proc/(pid)/statm -func (p *Process) fillFromStatmWithContext() (*MemoryInfoStat, *MemoryInfoExStat, error) { +func (p *Process) fillFromStatmWithContext(ctx context.Context) (*MemoryInfoStat, *MemoryInfoExStat, error) { pid := p.Pid - memPath := common.HostProc(strconv.Itoa(int(pid)), "statm") + memPath := common.HostProcWithContext(ctx, strconv.Itoa(int(pid)), "statm") contents, err := ioutil.ReadFile(memPath) if err != nil { return nil, nil, err @@ -790,7 +791,7 @@ func (p *Process) fillFromStatmWithContext() (*MemoryInfoStat, *MemoryInfoExStat // Get name from /proc/(pid)/comm or /proc/(pid)/status func (p *Process) fillNameWithContext(ctx context.Context) error { - err := p.fillFromCommWithContext() + err := p.fillFromCommWithContext(ctx) if err == nil && p.name != "" && len(p.name) < 15 { return nil } @@ -798,9 +799,9 @@ func (p *Process) fillNameWithContext(ctx context.Context) error { } // Get name from /proc/(pid)/comm -func (p *Process) fillFromCommWithContext() error { +func (p *Process) fillFromCommWithContext(ctx context.Context) error { pid := p.Pid - statPath := common.HostProc(strconv.Itoa(int(pid)), "comm") + statPath := common.HostProcWithContext(ctx, strconv.Itoa(int(pid)), "comm") contents, err := ioutil.ReadFile(statPath) if err != nil { return err @@ -817,7 +818,7 @@ func (p *Process) fillFromStatus() error { func (p *Process) fillFromStatusWithContext(ctx context.Context) error { pid := p.Pid - statPath := common.HostProc(strconv.Itoa(int(pid)), "status") + statPath := common.HostProcWithContext(ctx, strconv.Itoa(int(pid)), "status") contents, err := ioutil.ReadFile(statPath) if err != nil { return err @@ -844,8 +845,6 @@ func (p *Process) fillFromStatusWithContext(ctx context.Context) error { extendedName := filepath.Base(cmdlineSlice[0]) if strings.HasPrefix(extendedName, p.name) { p.name = extendedName - } else { - p.name = cmdlineSlice[0] } } } @@ -1022,9 +1021,9 @@ func (p *Process) fillFromTIDStatWithContext(ctx context.Context, tid int32) (ui var statPath string if tid == -1 { - statPath = common.HostProc(strconv.Itoa(int(pid)), "stat") + statPath = common.HostProcWithContext(ctx, strconv.Itoa(int(pid)), "stat") } else { - statPath = common.HostProc(strconv.Itoa(int(pid)), "task", strconv.Itoa(int(tid)), "stat") + statPath = common.HostProcWithContext(ctx, strconv.Itoa(int(pid)), "task", strconv.Itoa(int(tid)), "stat") } contents, err := ioutil.ReadFile(statPath) @@ -1128,7 +1127,7 @@ func (p *Process) fillFromStatWithContext(ctx context.Context) (uint64, int32, * } func pidsWithContext(ctx context.Context) ([]int32, error) { - return readPidsFromDir(common.HostProc()) + return readPidsFromDir(common.HostProcWithContext(ctx)) } func ProcessesWithContext(ctx context.Context) ([]*Process, error) { diff --git a/vendor/github.com/shirou/gopsutil/v3/process/process_openbsd.go b/vendor/github.com/shirou/gopsutil/v3/process/process_openbsd.go index cbb1a77f69..a58c5eb113 100644 --- a/vendor/github.com/shirou/gopsutil/v3/process/process_openbsd.go +++ b/vendor/github.com/shirou/gopsutil/v3/process/process_openbsd.go @@ -60,8 +60,6 @@ func (p *Process) NameWithContext(ctx context.Context) (string, error) { extendedName := filepath.Base(cmdlineSlice[0]) if strings.HasPrefix(extendedName, p.name) { name = extendedName - } else { - name = cmdlineSlice[0] } } } diff --git a/vendor/github.com/shirou/gopsutil/v3/process/process_posix.go b/vendor/github.com/shirou/gopsutil/v3/process/process_posix.go index 88e2bff537..a01f9ecfc0 100644 --- a/vendor/github.com/shirou/gopsutil/v3/process/process_posix.go +++ b/vendor/github.com/shirou/gopsutil/v3/process/process_posix.go @@ -14,8 +14,9 @@ import ( "strings" "syscall" - "github.com/shirou/gopsutil/v3/internal/common" "golang.org/x/sys/unix" + + "github.com/shirou/gopsutil/v3/internal/common" ) type Signal = syscall.Signal @@ -108,8 +109,8 @@ func PidExistsWithContext(ctx context.Context, pid int32) (bool, error) { return false, err } - if isMount(common.HostProc()) { // if //proc exists and is mounted, check if //proc/ folder exists - _, err := os.Stat(common.HostProc(strconv.Itoa(int(pid)))) + if isMount(common.HostProcWithContext(ctx)) { // if //proc exists and is mounted, check if //proc/ folder exists + _, err := os.Stat(common.HostProcWithContext(ctx, strconv.Itoa(int(pid)))) if os.IsNotExist(err) { return false, nil } @@ -121,7 +122,7 @@ func PidExistsWithContext(ctx context.Context, pid int32) (bool, error) { if err == nil { return true, nil } - if err.Error() == "os: process already finished" { + if errors.Is(err, os.ErrProcessDone) { return false, nil } var errno syscall.Errno diff --git a/vendor/github.com/shirou/gopsutil/v3/process/process_solaris.go b/vendor/github.com/shirou/gopsutil/v3/process/process_solaris.go index 4f10a67bc6..ad1c3cfc19 100644 --- a/vendor/github.com/shirou/gopsutil/v3/process/process_solaris.go +++ b/vendor/github.com/shirou/gopsutil/v3/process/process_solaris.go @@ -30,7 +30,7 @@ type MemoryMapsStat struct { type MemoryInfoExStat struct{} func pidsWithContext(ctx context.Context) ([]int32, error) { - return readPidsFromDir(common.HostProc()) + return readPidsFromDir(common.HostProcWithContext(ctx)) } func ProcessesWithContext(ctx context.Context) ([]*Process, error) { @@ -199,7 +199,7 @@ func (p *Process) EnvironWithContext(ctx context.Context) ([]string, error) { func (p *Process) fillFromfdListWithContext(ctx context.Context) (string, []string, error) { pid := p.Pid - statPath := common.HostProc(strconv.Itoa(int(pid)), "fd") + statPath := common.HostProcWithContext(ctx, strconv.Itoa(int(pid)), "fd") d, err := os.Open(statPath) if err != nil { return statPath, []string{}, err @@ -211,7 +211,7 @@ func (p *Process) fillFromfdListWithContext(ctx context.Context) (string, []stri func (p *Process) fillFromPathCwdWithContext(ctx context.Context) (string, error) { pid := p.Pid - cwdPath := common.HostProc(strconv.Itoa(int(pid)), "path", "cwd") + cwdPath := common.HostProcWithContext(ctx, strconv.Itoa(int(pid)), "path", "cwd") cwd, err := os.Readlink(cwdPath) if err != nil { return "", err @@ -221,7 +221,7 @@ func (p *Process) fillFromPathCwdWithContext(ctx context.Context) (string, error func (p *Process) fillFromPathAOutWithContext(ctx context.Context) (string, error) { pid := p.Pid - cwdPath := common.HostProc(strconv.Itoa(int(pid)), "path", "a.out") + cwdPath := common.HostProcWithContext(ctx, strconv.Itoa(int(pid)), "path", "a.out") exe, err := os.Readlink(cwdPath) if err != nil { return "", err @@ -231,7 +231,7 @@ func (p *Process) fillFromPathAOutWithContext(ctx context.Context) (string, erro func (p *Process) fillFromExecnameWithContext(ctx context.Context) (string, error) { pid := p.Pid - execNamePath := common.HostProc(strconv.Itoa(int(pid)), "execname") + execNamePath := common.HostProcWithContext(ctx, strconv.Itoa(int(pid)), "execname") exe, err := ioutil.ReadFile(execNamePath) if err != nil { return "", err @@ -241,7 +241,7 @@ func (p *Process) fillFromExecnameWithContext(ctx context.Context) (string, erro func (p *Process) fillFromCmdlineWithContext(ctx context.Context) (string, error) { pid := p.Pid - cmdPath := common.HostProc(strconv.Itoa(int(pid)), "cmdline") + cmdPath := common.HostProcWithContext(ctx, strconv.Itoa(int(pid)), "cmdline") cmdline, err := ioutil.ReadFile(cmdPath) if err != nil { return "", err @@ -258,7 +258,7 @@ func (p *Process) fillFromCmdlineWithContext(ctx context.Context) (string, error func (p *Process) fillSliceFromCmdlineWithContext(ctx context.Context) ([]string, error) { pid := p.Pid - cmdPath := common.HostProc(strconv.Itoa(int(pid)), "cmdline") + cmdPath := common.HostProcWithContext(ctx, strconv.Itoa(int(pid)), "cmdline") cmdline, err := ioutil.ReadFile(cmdPath) if err != nil { return nil, err diff --git a/vendor/github.com/shirou/gopsutil/v3/process/process_windows.go b/vendor/github.com/shirou/gopsutil/v3/process/process_windows.go index 18f4f94557..14ed0309fe 100644 --- a/vendor/github.com/shirou/gopsutil/v3/process/process_windows.go +++ b/vendor/github.com/shirou/gopsutil/v3/process/process_windows.go @@ -10,6 +10,7 @@ import ( "fmt" "io" "os" + "path/filepath" "reflect" "strings" "syscall" @@ -319,18 +320,19 @@ func (p *Process) PpidWithContext(ctx context.Context) (int32, error) { } func (p *Process) NameWithContext(ctx context.Context) (string, error) { - ppid, _, name, err := getFromSnapProcess(p.Pid) - if err != nil { - return "", fmt.Errorf("could not get Name: %s", err) + if p.Pid == 0 { + return "System Idle Process", nil + } + if p.Pid == 4 { + return "System", nil } - // if no errors and not cached already, cache ppid - p.parent = ppid - if 0 == p.getPpid() { - p.setPpid(ppid) + exe, err := p.ExeWithContext(ctx) + if err != nil { + return "", fmt.Errorf("could not get Name: %s", err) } - return name, nil + return filepath.Base(exe), nil } func (p *Process) TgidWithContext(ctx context.Context) (int32, error) { @@ -408,7 +410,7 @@ func (p *Process) CwdWithContext(_ context.Context) (string, error) { } if userProcParams.CurrentDirectoryPathNameLength > 0 { cwd := readProcessMemory(syscall.Handle(h), procIs32Bits, uint64(userProcParams.CurrentDirectoryPathAddress), uint(userProcParams.CurrentDirectoryPathNameLength)) - if len(cwd) != int(userProcParams.CurrentDirectoryPathAddress) { + if len(cwd) != int(userProcParams.CurrentDirectoryPathNameLength) { return "", errors.New("cannot read current working directory") } @@ -987,15 +989,9 @@ func is32BitProcess(h windows.Handle) bool { var procIs32Bits bool switch processorArchitecture { - case PROCESSOR_ARCHITECTURE_INTEL: - fallthrough - case PROCESSOR_ARCHITECTURE_ARM: + case PROCESSOR_ARCHITECTURE_INTEL, PROCESSOR_ARCHITECTURE_ARM: procIs32Bits = true - case PROCESSOR_ARCHITECTURE_ARM64: - fallthrough - case PROCESSOR_ARCHITECTURE_IA64: - fallthrough - case PROCESSOR_ARCHITECTURE_AMD64: + case PROCESSOR_ARCHITECTURE_ARM64, PROCESSOR_ARCHITECTURE_IA64, PROCESSOR_ARCHITECTURE_AMD64: var wow64 uint ret, _, _ := common.ProcNtQueryInformationProcess.Call( diff --git a/vendor/github.com/shirou/gopsutil/v3/process/process_windows_32bit.go b/vendor/github.com/shirou/gopsutil/v3/process/process_windows_32bit.go index 982287d939..db4d453349 100644 --- a/vendor/github.com/shirou/gopsutil/v3/process/process_windows_32bit.go +++ b/vendor/github.com/shirou/gopsutil/v3/process/process_windows_32bit.go @@ -8,9 +8,8 @@ import ( "syscall" "unsafe" - "golang.org/x/sys/windows" - "github.com/shirou/gopsutil/v3/internal/common" + "golang.org/x/sys/windows" ) type PROCESS_MEMORY_COUNTERS struct { diff --git a/vendor/github.com/shoenig/go-m1cpu/.golangci.yaml b/vendor/github.com/shoenig/go-m1cpu/.golangci.yaml new file mode 100644 index 0000000000..dc6fefb979 --- /dev/null +++ b/vendor/github.com/shoenig/go-m1cpu/.golangci.yaml @@ -0,0 +1,12 @@ +run: + timeout: 5m +linters: + enable: + - gofmt + - errcheck + - errname + - errorlint + - bodyclose + - durationcheck + - whitespace + diff --git a/vendor/github.com/shoenig/go-m1cpu/LICENSE b/vendor/github.com/shoenig/go-m1cpu/LICENSE new file mode 100644 index 0000000000..e87a115e46 --- /dev/null +++ b/vendor/github.com/shoenig/go-m1cpu/LICENSE @@ -0,0 +1,363 @@ +Mozilla Public License, version 2.0 + +1. Definitions + +1.1. "Contributor" + + means each individual or legal entity that creates, contributes to the + creation of, or owns Covered Software. + +1.2. "Contributor Version" + + means the combination of the Contributions of others (if any) used by a + Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + + means Source Code Form to which the initial Contributor has attached the + notice in Exhibit A, the Executable Form of such Source Code Form, and + Modifications of such Source Code Form, in each case including portions + thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + a. that the initial Contributor has attached the notice described in + Exhibit B to the Covered Software; or + + b. that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the terms of + a Secondary License. + +1.6. "Executable Form" + + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + + means a work that combines Covered Software with other material, in a + separate file or files, that is not Covered Software. + +1.8. "License" + + means this document. + +1.9. "Licensable" + + means having the right to grant, to the maximum extent possible, whether + at the time of the initial grant or subsequently, any and all of the + rights conveyed by this License. + +1.10. "Modifications" + + means any of the following: + + a. any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered Software; or + + b. any new file in Source Code Form that contains any Covered Software. + +1.11. "Patent Claims" of a Contributor + + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the License, + by the making, using, selling, offering for sale, having made, import, + or transfer of either its Contributions or its Contributor Version. + +1.12. "Secondary License" + + means either the GNU General Public License, Version 2.0, the GNU Lesser + General Public License, Version 2.1, the GNU Affero General Public + License, Version 3.0, or any later versions of those licenses. + +1.13. "Source Code Form" + + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that controls, is + controlled by, or is under common control with You. For purposes of this + definition, "control" means (a) the power, direct or indirect, to cause + the direction or management of such entity, whether by contract or + otherwise, or (b) ownership of more than fifty percent (50%) of the + outstanding shares or beneficial ownership of such entity. + + +2. License Grants and Conditions + +2.1. Grants + + Each Contributor hereby grants You a world-wide, royalty-free, + non-exclusive license: + + a. under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + + b. under Patent Claims of such Contributor to make, use, sell, offer for + sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + + The licenses granted in Section 2.1 with respect to any Contribution + become effective for each Contribution on the date the Contributor first + distributes such Contribution. + +2.3. Limitations on Grant Scope + + The licenses granted in this Section 2 are the only rights granted under + this License. No additional rights or licenses will be implied from the + distribution or licensing of Covered Software under this License. + Notwithstanding Section 2.1(b) above, no patent license is granted by a + Contributor: + + a. for any code that a Contributor has removed from Covered Software; or + + b. for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + + c. under Patent Claims infringed by Covered Software in the absence of + its Contributions. + + This License does not grant any rights in the trademarks, service marks, + or logos of any Contributor (except as may be necessary to comply with + the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + + No Contributor makes additional grants as a result of Your choice to + distribute the Covered Software under a subsequent version of this + License (see Section 10.2) or under the terms of a Secondary License (if + permitted under the terms of Section 3.3). + +2.5. Representation + + Each Contributor represents that the Contributor believes its + Contributions are its original creation(s) or it has sufficient rights to + grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + + This License is not intended to limit any rights You have under + applicable copyright doctrines of fair use, fair dealing, or other + equivalents. + +2.7. Conditions + + Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in + Section 2.1. + + +3. Responsibilities + +3.1. Distribution of Source Form + + All distribution of Covered Software in Source Code Form, including any + Modifications that You create or to which You contribute, must be under + the terms of this License. You must inform recipients that the Source + Code Form of the Covered Software is governed by the terms of this + License, and how they can obtain a copy of this License. You may not + attempt to alter or restrict the recipients' rights in the Source Code + Form. + +3.2. Distribution of Executable Form + + If You distribute Covered Software in Executable Form then: + + a. such Covered Software must also be made available in Source Code Form, + as described in Section 3.1, and You must inform recipients of the + Executable Form how they can obtain a copy of such Source Code Form by + reasonable means in a timely manner, at a charge no more than the cost + of distribution to the recipient; and + + b. You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter the + recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + + You may create and distribute a Larger Work under terms of Your choice, + provided that You also comply with the requirements of this License for + the Covered Software. If the Larger Work is a combination of Covered + Software with a work governed by one or more Secondary Licenses, and the + Covered Software is not Incompatible With Secondary Licenses, this + License permits You to additionally distribute such Covered Software + under the terms of such Secondary License(s), so that the recipient of + the Larger Work may, at their option, further distribute the Covered + Software under the terms of either this License or such Secondary + License(s). + +3.4. Notices + + You may not remove or alter the substance of any license notices + (including copyright notices, patent notices, disclaimers of warranty, or + limitations of liability) contained within the Source Code Form of the + Covered Software, except that You may alter any license notices to the + extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + + You may choose to offer, and to charge a fee for, warranty, support, + indemnity or liability obligations to one or more recipients of Covered + Software. However, You may do so only on Your own behalf, and not on + behalf of any Contributor. You must make it absolutely clear that any + such warranty, support, indemnity, or liability obligation is offered by + You alone, and You hereby agree to indemnify every Contributor for any + liability incurred by such Contributor as a result of warranty, support, + indemnity or liability terms You offer. You may include additional + disclaimers of warranty and limitations of liability specific to any + jurisdiction. + +4. Inability to Comply Due to Statute or Regulation + + If it is impossible for You to comply with any of the terms of this License + with respect to some or all of the Covered Software due to statute, + judicial order, or regulation then You must: (a) comply with the terms of + this License to the maximum extent possible; and (b) describe the + limitations and the code they affect. Such description must be placed in a + text file included with all distributions of the Covered Software under + this License. Except to the extent prohibited by statute or regulation, + such description must be sufficiently detailed for a recipient of ordinary + skill to be able to understand it. + +5. Termination + +5.1. The rights granted under this License will terminate automatically if You + fail to comply with any of its terms. However, if You become compliant, + then the rights granted under this License from a particular Contributor + are reinstated (a) provisionally, unless and until such Contributor + explicitly and finally terminates Your grants, and (b) on an ongoing + basis, if such Contributor fails to notify You of the non-compliance by + some reasonable means prior to 60 days after You have come back into + compliance. Moreover, Your grants from a particular Contributor are + reinstated on an ongoing basis if such Contributor notifies You of the + non-compliance by some reasonable means, this is the first time You have + received notice of non-compliance with this License from such + Contributor, and You become compliant prior to 30 days after Your receipt + of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent + infringement claim (excluding declaratory judgment actions, + counter-claims, and cross-claims) alleging that a Contributor Version + directly or indirectly infringes any patent, then the rights granted to + You by any and all Contributors for the Covered Software under Section + 2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user + license agreements (excluding distributors and resellers) which have been + validly granted by You or Your distributors under this License prior to + termination shall survive termination. + +6. Disclaimer of Warranty + + Covered Software is provided under this License on an "as is" basis, + without warranty of any kind, either expressed, implied, or statutory, + including, without limitation, warranties that the Covered Software is free + of defects, merchantable, fit for a particular purpose or non-infringing. + The entire risk as to the quality and performance of the Covered Software + is with You. Should any Covered Software prove defective in any respect, + You (not any Contributor) assume the cost of any necessary servicing, + repair, or correction. This disclaimer of warranty constitutes an essential + part of this License. No use of any Covered Software is authorized under + this License except under this disclaimer. + +7. Limitation of Liability + + Under no circumstances and under no legal theory, whether tort (including + negligence), contract, or otherwise, shall any Contributor, or anyone who + distributes Covered Software as permitted above, be liable to You for any + direct, indirect, special, incidental, or consequential damages of any + character including, without limitation, damages for lost profits, loss of + goodwill, work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses, even if such party shall have been + informed of the possibility of such damages. This limitation of liability + shall not apply to liability for death or personal injury resulting from + such party's negligence to the extent applicable law prohibits such + limitation. Some jurisdictions do not allow the exclusion or limitation of + incidental or consequential damages, so this exclusion and limitation may + not apply to You. + +8. Litigation + + Any litigation relating to this License may be brought only in the courts + of a jurisdiction where the defendant maintains its principal place of + business and such litigation shall be governed by laws of that + jurisdiction, without reference to its conflict-of-law provisions. Nothing + in this Section shall prevent a party's ability to bring cross-claims or + counter-claims. + +9. Miscellaneous + + This License represents the complete agreement concerning the subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the extent + necessary to make it enforceable. Any law or regulation which provides that + the language of a contract shall be construed against the drafter shall not + be used to construe this License against a Contributor. + + +10. Versions of the License + +10.1. New Versions + + Mozilla Foundation is the license steward. Except as provided in Section + 10.3, no one other than the license steward has the right to modify or + publish new versions of this License. Each version will be given a + distinguishing version number. + +10.2. Effect of New Versions + + You may distribute the Covered Software under the terms of the version + of the License under which You originally received the Covered Software, + or under the terms of any subsequent version published by the license + steward. + +10.3. Modified Versions + + If you create software not governed by this License, and you want to + create a new license for such software, you may create and use a + modified version of this License if you rename the license and remove + any references to the name of the license steward (except to note that + such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary + Licenses If You choose to distribute Source Code Form that is + Incompatible With Secondary Licenses under the terms of this version of + the License, the notice described in Exhibit B of this License must be + attached. + +Exhibit A - Source Code Form License Notice + + This Source Code Form is subject to the + terms of the Mozilla Public License, v. + 2.0. If a copy of the MPL was not + distributed with this file, You can + obtain one at + http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular file, +then You may include the notice in a location (such as a LICENSE file in a +relevant directory) where a recipient would be likely to look for such a +notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice + + This Source Code Form is "Incompatible + With Secondary Licenses", as defined by + the Mozilla Public License, v. 2.0. + diff --git a/vendor/github.com/shoenig/go-m1cpu/Makefile b/vendor/github.com/shoenig/go-m1cpu/Makefile new file mode 100644 index 0000000000..28d786397d --- /dev/null +++ b/vendor/github.com/shoenig/go-m1cpu/Makefile @@ -0,0 +1,12 @@ +SHELL = bash + +default: test + +.PHONY: test +test: + @echo "--> Running Tests ..." + @go test -v -race ./... + +vet: + @echo "--> Vet Go sources ..." + @go vet ./... diff --git a/vendor/github.com/shoenig/go-m1cpu/README.md b/vendor/github.com/shoenig/go-m1cpu/README.md new file mode 100644 index 0000000000..399657acf8 --- /dev/null +++ b/vendor/github.com/shoenig/go-m1cpu/README.md @@ -0,0 +1,66 @@ +# m1cpu + +[![Go Reference](https://pkg.go.dev/badge/github.com/shoenig/go-m1cpu.svg)](https://pkg.go.dev/github.com/shoenig/go-m1cpu) +[![MPL License](https://img.shields.io/github/license/shoenig/go-m1cpu?color=g&style=flat-square)](https://github.com/shoenig/go-m1cpu/blob/main/LICENSE) +[![Run CI Tests](https://github.com/shoenig/go-m1cpu/actions/workflows/ci.yaml/badge.svg)](https://github.com/shoenig/go-m1cpu/actions/workflows/ci.yaml) + +The `go-m1cpu` module is a library for inspecting Apple Silicon CPUs in Go. + +Use the `m1cpu` Go package for looking up the CPU frequency for Apple M1 and M2 CPUs. + +# Install + +```shell +go get github.com/shoenig/go-m1cpu@latest +``` + +# CGO + +This package requires the use of [CGO](https://go.dev/blog/cgo). + +Extracting the CPU properties is done via Apple's [IOKit](https://developer.apple.com/documentation/iokit?language=objc) +framework, which is accessible only through system C libraries. + +# Example + +Simple Go program to print Apple Silicon M1/M2 CPU speeds. + +```go +package main + +import ( + "fmt" + + "github.com/shoenig/go-m1cpu" +) + +func main() { + fmt.Println("Apple Silicon", m1cpu.IsAppleSilicon()) + + fmt.Println("pCore GHz", m1cpu.PCoreGHz()) + fmt.Println("eCore GHz", m1cpu.ECoreGHz()) + + fmt.Println("pCore Hz", m1cpu.PCoreHz()) + fmt.Println("eCore Hz", m1cpu.ECoreHz()) +} +``` + +Using `go test` to print out available information. + +``` +➜ go test -v -run Show +=== RUN Test_Show + cpu_test.go:42: pCore Hz 3504000000 + cpu_test.go:43: eCore Hz 2424000000 + cpu_test.go:44: pCore GHz 3.504 + cpu_test.go:45: eCore GHz 2.424 + cpu_test.go:46: pCore count 8 + cpu_test.go:47: eCoreCount 4 + cpu_test.go:50: pCore Caches 196608 131072 16777216 + cpu_test.go:53: eCore Caches 131072 65536 4194304 +--- PASS: Test_Show (0.00s) +``` + +# License + +Open source under the [MPL](LICENSE) diff --git a/vendor/github.com/shoenig/go-m1cpu/cpu.go b/vendor/github.com/shoenig/go-m1cpu/cpu.go new file mode 100644 index 0000000000..502a8cce92 --- /dev/null +++ b/vendor/github.com/shoenig/go-m1cpu/cpu.go @@ -0,0 +1,213 @@ +//go:build darwin && arm64 && cgo + +package m1cpu + +// #cgo LDFLAGS: -framework CoreFoundation -framework IOKit +// #include +// #include +// #include +// #include +// +// #if !defined(MAC_OS_VERSION_12_0) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_VERSION_12_0 +// #define kIOMainPortDefault kIOMasterPortDefault +// #endif +// +// #define HzToGHz(hz) ((hz) / 1000000000.0) +// +// UInt64 global_pCoreHz; +// UInt64 global_eCoreHz; +// int global_pCoreCount; +// int global_eCoreCount; +// int global_pCoreL1InstCacheSize; +// int global_eCoreL1InstCacheSize; +// int global_pCoreL1DataCacheSize; +// int global_eCoreL1DataCacheSize; +// int global_pCoreL2CacheSize; +// int global_eCoreL2CacheSize; +// char global_brand[32]; +// +// UInt64 getFrequency(CFTypeRef typeRef) { +// CFDataRef cfData = typeRef; +// +// CFIndex size = CFDataGetLength(cfData); +// UInt8 buf[size]; +// CFDataGetBytes(cfData, CFRangeMake(0, size), buf); +// +// UInt8 b1 = buf[size-5]; +// UInt8 b2 = buf[size-6]; +// UInt8 b3 = buf[size-7]; +// UInt8 b4 = buf[size-8]; +// +// UInt64 pCoreHz = 0x00000000FFFFFFFF & ((b1<<24) | (b2 << 16) | (b3 << 8) | (b4)); +// return pCoreHz; +// } +// +// int sysctl_int(const char * name) { +// int value = -1; +// size_t size = 8; +// sysctlbyname(name, &value, &size, NULL, 0); +// return value; +// } +// +// void sysctl_string(const char * name, char * dest) { +// size_t size = 32; +// sysctlbyname(name, dest, &size, NULL, 0); +// } +// +// void initialize() { +// global_pCoreCount = sysctl_int("hw.perflevel0.physicalcpu"); +// global_eCoreCount = sysctl_int("hw.perflevel1.physicalcpu"); +// global_pCoreL1InstCacheSize = sysctl_int("hw.perflevel0.l1icachesize"); +// global_eCoreL1InstCacheSize = sysctl_int("hw.perflevel1.l1icachesize"); +// global_pCoreL1DataCacheSize = sysctl_int("hw.perflevel0.l1dcachesize"); +// global_eCoreL1DataCacheSize = sysctl_int("hw.perflevel1.l1dcachesize"); +// global_pCoreL2CacheSize = sysctl_int("hw.perflevel0.l2cachesize"); +// global_eCoreL2CacheSize = sysctl_int("hw.perflevel1.l2cachesize"); +// sysctl_string("machdep.cpu.brand_string", global_brand); +// +// CFMutableDictionaryRef matching = IOServiceMatching("AppleARMIODevice"); +// io_iterator_t iter; +// IOServiceGetMatchingServices(kIOMainPortDefault, matching, &iter); +// +// const size_t bufsize = 512; +// io_object_t obj; +// while ((obj = IOIteratorNext(iter))) { +// char class[bufsize]; +// IOObjectGetClass(obj, class); +// char name[bufsize]; +// IORegistryEntryGetName(obj, name); +// +// if (strncmp(name, "pmgr", bufsize) == 0) { +// CFTypeRef pCoreRef = IORegistryEntryCreateCFProperty(obj, CFSTR("voltage-states5-sram"), kCFAllocatorDefault, 0); +// CFTypeRef eCoreRef = IORegistryEntryCreateCFProperty(obj, CFSTR("voltage-states1-sram"), kCFAllocatorDefault, 0); +// +// long long pCoreHz = getFrequency(pCoreRef); +// long long eCoreHz = getFrequency(eCoreRef); +// +// global_pCoreHz = pCoreHz; +// global_eCoreHz = eCoreHz; +// return; +// } +// } +// } +// +// UInt64 eCoreHz() { +// return global_eCoreHz; +// } +// +// UInt64 pCoreHz() { +// return global_pCoreHz; +// } +// +// Float64 eCoreGHz() { +// return HzToGHz(global_eCoreHz); +// } +// +// Float64 pCoreGHz() { +// return HzToGHz(global_pCoreHz); +// } +// +// int pCoreCount() { +// return global_pCoreCount; +// } +// +// int eCoreCount() { +// return global_eCoreCount; +// } +// +// int pCoreL1InstCacheSize() { +// return global_pCoreL1InstCacheSize; +// } +// +// int pCoreL1DataCacheSize() { +// return global_pCoreL1DataCacheSize; +// } +// +// int pCoreL2CacheSize() { +// return global_pCoreL2CacheSize; +// } +// +// int eCoreL1InstCacheSize() { +// return global_eCoreL1InstCacheSize; +// } +// +// int eCoreL1DataCacheSize() { +// return global_eCoreL1DataCacheSize; +// } +// +// int eCoreL2CacheSize() { +// return global_eCoreL2CacheSize; +// } +// +// char * modelName() { +// return global_brand; +// } +import "C" + +func init() { + C.initialize() +} + +// IsAppleSilicon returns true on this platform. +func IsAppleSilicon() bool { + return true +} + +// PCoreHZ returns the max frequency in Hertz of the P-Core of an Apple Silicon CPU. +func PCoreHz() uint64 { + return uint64(C.pCoreHz()) +} + +// ECoreHZ returns the max frequency in Hertz of the E-Core of an Apple Silicon CPU. +func ECoreHz() uint64 { + return uint64(C.eCoreHz()) +} + +// PCoreGHz returns the max frequency in Gigahertz of the P-Core of an Apple Silicon CPU. +func PCoreGHz() float64 { + return float64(C.pCoreGHz()) +} + +// ECoreGHz returns the max frequency in Gigahertz of the E-Core of an Apple Silicon CPU. +func ECoreGHz() float64 { + return float64(C.eCoreGHz()) +} + +// PCoreCount returns the number of physical P (performance) cores. +func PCoreCount() int { + return int(C.pCoreCount()) +} + +// ECoreCount returns the number of physical E (efficiency) cores. +func ECoreCount() int { + return int(C.eCoreCount()) +} + +// PCoreCacheSize returns the sizes of the P (performance) core cache sizes +// in the order of +// +// - L1 instruction cache +// - L1 data cache +// - L2 cache +func PCoreCache() (int, int, int) { + return int(C.pCoreL1InstCacheSize()), + int(C.pCoreL1DataCacheSize()), + int(C.pCoreL2CacheSize()) +} + +// ECoreCacheSize returns the sizes of the E (efficiency) core cache sizes +// in the order of +// +// - L1 instruction cache +// - L1 data cache +// - L2 cache +func ECoreCache() (int, int, int) { + return int(C.eCoreL1InstCacheSize()), + int(C.eCoreL1DataCacheSize()), + int(C.eCoreL2CacheSize()) +} + +// ModelName returns the model name of the CPU. +func ModelName() string { + return C.GoString(C.modelName()) +} diff --git a/vendor/github.com/shoenig/go-m1cpu/incompatible.go b/vendor/github.com/shoenig/go-m1cpu/incompatible.go new file mode 100644 index 0000000000..d425025aa8 --- /dev/null +++ b/vendor/github.com/shoenig/go-m1cpu/incompatible.go @@ -0,0 +1,53 @@ +//go:build !darwin || !arm64 || !cgo + +package m1cpu + +// IsAppleSilicon return false on this platform. +func IsAppleSilicon() bool { + return false +} + +// PCoreHZ requires darwin/arm64 +func PCoreHz() uint64 { + panic("m1cpu: not a darwin/arm64 system") +} + +// ECoreHZ requires darwin/arm64 +func ECoreHz() uint64 { + panic("m1cpu: not a darwin/arm64 system") +} + +// PCoreGHz requires darwin/arm64 +func PCoreGHz() float64 { + panic("m1cpu: not a darwin/arm64 system") +} + +// ECoreGHz requires darwin/arm64 +func ECoreGHz() float64 { + panic("m1cpu: not a darwin/arm64 system") +} + +// PCoreCount requires darwin/arm64 +func PCoreCount() int { + panic("m1cpu: not a darwin/arm64 system") +} + +// ECoreCount requires darwin/arm64 +func ECoreCount() int { + panic("m1cpu: not a darwin/arm64 system") +} + +// PCoreCacheSize requires darwin/arm64 +func PCoreCache() (int, int, int) { + panic("m1cpu: not a darwin/arm64 system") +} + +// ECoreCacheSize requires darwin/arm64 +func ECoreCache() (int, int, int) { + panic("m1cpu: not a darwin/arm64 system") +} + +// ModelName requires darwin/arm64 +func ModelName() string { + panic("m1cpu: not a darwin/arm64 system") +} diff --git a/vendor/github.com/stretchr/testify/assert/assertion_compare.go b/vendor/github.com/stretchr/testify/assert/assertion_compare.go index 95d8e59da6..b774da88d8 100644 --- a/vendor/github.com/stretchr/testify/assert/assertion_compare.go +++ b/vendor/github.com/stretchr/testify/assert/assertion_compare.go @@ -352,9 +352,9 @@ func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) { // Greater asserts that the first element is greater than the second // -// assert.Greater(t, 2, 1) -// assert.Greater(t, float64(2), float64(1)) -// assert.Greater(t, "b", "a") +// assert.Greater(t, 2, 1) +// assert.Greater(t, float64(2), float64(1)) +// assert.Greater(t, "b", "a") func Greater(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -364,10 +364,10 @@ func Greater(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface // GreaterOrEqual asserts that the first element is greater than or equal to the second // -// assert.GreaterOrEqual(t, 2, 1) -// assert.GreaterOrEqual(t, 2, 2) -// assert.GreaterOrEqual(t, "b", "a") -// assert.GreaterOrEqual(t, "b", "b") +// assert.GreaterOrEqual(t, 2, 1) +// assert.GreaterOrEqual(t, 2, 2) +// assert.GreaterOrEqual(t, "b", "a") +// assert.GreaterOrEqual(t, "b", "b") func GreaterOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -377,9 +377,9 @@ func GreaterOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...in // Less asserts that the first element is less than the second // -// assert.Less(t, 1, 2) -// assert.Less(t, float64(1), float64(2)) -// assert.Less(t, "a", "b") +// assert.Less(t, 1, 2) +// assert.Less(t, float64(1), float64(2)) +// assert.Less(t, "a", "b") func Less(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -389,10 +389,10 @@ func Less(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) // LessOrEqual asserts that the first element is less than or equal to the second // -// assert.LessOrEqual(t, 1, 2) -// assert.LessOrEqual(t, 2, 2) -// assert.LessOrEqual(t, "a", "b") -// assert.LessOrEqual(t, "b", "b") +// assert.LessOrEqual(t, 1, 2) +// assert.LessOrEqual(t, 2, 2) +// assert.LessOrEqual(t, "a", "b") +// assert.LessOrEqual(t, "b", "b") func LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -402,8 +402,8 @@ func LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...inter // Positive asserts that the specified element is positive // -// assert.Positive(t, 1) -// assert.Positive(t, 1.23) +// assert.Positive(t, 1) +// assert.Positive(t, 1.23) func Positive(t TestingT, e interface{}, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -414,8 +414,8 @@ func Positive(t TestingT, e interface{}, msgAndArgs ...interface{}) bool { // Negative asserts that the specified element is negative // -// assert.Negative(t, -1) -// assert.Negative(t, -1.23) +// assert.Negative(t, -1) +// assert.Negative(t, -1.23) func Negative(t TestingT, e interface{}, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() diff --git a/vendor/github.com/stretchr/testify/assert/assertion_format.go b/vendor/github.com/stretchr/testify/assert/assertion_format.go index 7880b8f943..84dbd6c790 100644 --- a/vendor/github.com/stretchr/testify/assert/assertion_format.go +++ b/vendor/github.com/stretchr/testify/assert/assertion_format.go @@ -22,9 +22,9 @@ func Conditionf(t TestingT, comp Comparison, msg string, args ...interface{}) bo // Containsf asserts that the specified string, list(array, slice...) or map contains the // specified substring or element. // -// assert.Containsf(t, "Hello World", "World", "error message %s", "formatted") -// assert.Containsf(t, ["Hello", "World"], "World", "error message %s", "formatted") -// assert.Containsf(t, {"Hello": "World"}, "Hello", "error message %s", "formatted") +// assert.Containsf(t, "Hello World", "World", "error message %s", "formatted") +// assert.Containsf(t, ["Hello", "World"], "World", "error message %s", "formatted") +// assert.Containsf(t, {"Hello": "World"}, "Hello", "error message %s", "formatted") func Containsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -56,7 +56,7 @@ func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string // Emptyf asserts that the specified object is empty. I.e. nil, "", false, 0 or either // a slice or a channel with len == 0. // -// assert.Emptyf(t, obj, "error message %s", "formatted") +// assert.Emptyf(t, obj, "error message %s", "formatted") func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -66,7 +66,7 @@ func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) boo // Equalf asserts that two objects are equal. // -// assert.Equalf(t, 123, 123, "error message %s", "formatted") +// assert.Equalf(t, 123, 123, "error message %s", "formatted") // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). Function equality @@ -81,8 +81,8 @@ func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, ar // EqualErrorf asserts that a function returned an error (i.e. not `nil`) // and that it is equal to the provided error. // -// actualObj, err := SomeFunction() -// assert.EqualErrorf(t, err, expectedErrorString, "error message %s", "formatted") +// actualObj, err := SomeFunction() +// assert.EqualErrorf(t, err, expectedErrorString, "error message %s", "formatted") func EqualErrorf(t TestingT, theError error, errString string, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -90,10 +90,27 @@ func EqualErrorf(t TestingT, theError error, errString string, msg string, args return EqualError(t, theError, errString, append([]interface{}{msg}, args...)...) } +// EqualExportedValuesf asserts that the types of two objects are equal and their public +// fields are also equal. This is useful for comparing structs that have private fields +// that could potentially differ. +// +// type S struct { +// Exported int +// notExported int +// } +// assert.EqualExportedValuesf(t, S{1, 2}, S{1, 3}, "error message %s", "formatted") => true +// assert.EqualExportedValuesf(t, S{1, 2}, S{2, 3}, "error message %s", "formatted") => false +func EqualExportedValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return EqualExportedValues(t, expected, actual, append([]interface{}{msg}, args...)...) +} + // EqualValuesf asserts that two objects are equal or convertable to the same types // and equal. // -// assert.EqualValuesf(t, uint32(123), int32(123), "error message %s", "formatted") +// assert.EqualValuesf(t, uint32(123), int32(123), "error message %s", "formatted") func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -103,10 +120,10 @@ func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg stri // Errorf asserts that a function returned an error (i.e. not `nil`). // -// actualObj, err := SomeFunction() -// if assert.Errorf(t, err, "error message %s", "formatted") { -// assert.Equal(t, expectedErrorf, err) -// } +// actualObj, err := SomeFunction() +// if assert.Errorf(t, err, "error message %s", "formatted") { +// assert.Equal(t, expectedErrorf, err) +// } func Errorf(t TestingT, err error, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -126,8 +143,8 @@ func ErrorAsf(t TestingT, err error, target interface{}, msg string, args ...int // ErrorContainsf asserts that a function returned an error (i.e. not `nil`) // and that the error contains the specified substring. // -// actualObj, err := SomeFunction() -// assert.ErrorContainsf(t, err, expectedErrorSubString, "error message %s", "formatted") +// actualObj, err := SomeFunction() +// assert.ErrorContainsf(t, err, expectedErrorSubString, "error message %s", "formatted") func ErrorContainsf(t TestingT, theError error, contains string, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -147,7 +164,7 @@ func ErrorIsf(t TestingT, err error, target error, msg string, args ...interface // Eventuallyf asserts that given condition will be met in waitFor time, // periodically checking target function each tick. // -// assert.Eventuallyf(t, func() bool { return true; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") +// assert.Eventuallyf(t, func() bool { return true; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") func Eventuallyf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -155,9 +172,34 @@ func Eventuallyf(t TestingT, condition func() bool, waitFor time.Duration, tick return Eventually(t, condition, waitFor, tick, append([]interface{}{msg}, args...)...) } +// EventuallyWithTf asserts that given condition will be met in waitFor time, +// periodically checking target function each tick. In contrast to Eventually, +// it supplies a CollectT to the condition function, so that the condition +// function can use the CollectT to call other assertions. +// The condition is considered "met" if no errors are raised in a tick. +// The supplied CollectT collects all errors from one tick (if there are any). +// If the condition is not met before waitFor, the collected errors of +// the last tick are copied to t. +// +// externalValue := false +// go func() { +// time.Sleep(8*time.Second) +// externalValue = true +// }() +// assert.EventuallyWithTf(t, func(c *assert.CollectT, "error message %s", "formatted") { +// // add assertions as needed; any assertion failure will fail the current tick +// assert.True(c, externalValue, "expected 'externalValue' to be true") +// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") +func EventuallyWithTf(t TestingT, condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return EventuallyWithT(t, condition, waitFor, tick, append([]interface{}{msg}, args...)...) +} + // Exactlyf asserts that two objects are equal in value and type. // -// assert.Exactlyf(t, int32(123), int64(123), "error message %s", "formatted") +// assert.Exactlyf(t, int32(123), int64(123), "error message %s", "formatted") func Exactlyf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -183,7 +225,7 @@ func FailNowf(t TestingT, failureMessage string, msg string, args ...interface{} // Falsef asserts that the specified value is false. // -// assert.Falsef(t, myBool, "error message %s", "formatted") +// assert.Falsef(t, myBool, "error message %s", "formatted") func Falsef(t TestingT, value bool, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -202,9 +244,9 @@ func FileExistsf(t TestingT, path string, msg string, args ...interface{}) bool // Greaterf asserts that the first element is greater than the second // -// assert.Greaterf(t, 2, 1, "error message %s", "formatted") -// assert.Greaterf(t, float64(2), float64(1), "error message %s", "formatted") -// assert.Greaterf(t, "b", "a", "error message %s", "formatted") +// assert.Greaterf(t, 2, 1, "error message %s", "formatted") +// assert.Greaterf(t, float64(2), float64(1), "error message %s", "formatted") +// assert.Greaterf(t, "b", "a", "error message %s", "formatted") func Greaterf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -214,10 +256,10 @@ func Greaterf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...in // GreaterOrEqualf asserts that the first element is greater than or equal to the second // -// assert.GreaterOrEqualf(t, 2, 1, "error message %s", "formatted") -// assert.GreaterOrEqualf(t, 2, 2, "error message %s", "formatted") -// assert.GreaterOrEqualf(t, "b", "a", "error message %s", "formatted") -// assert.GreaterOrEqualf(t, "b", "b", "error message %s", "formatted") +// assert.GreaterOrEqualf(t, 2, 1, "error message %s", "formatted") +// assert.GreaterOrEqualf(t, 2, 2, "error message %s", "formatted") +// assert.GreaterOrEqualf(t, "b", "a", "error message %s", "formatted") +// assert.GreaterOrEqualf(t, "b", "b", "error message %s", "formatted") func GreaterOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -228,7 +270,7 @@ func GreaterOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, arg // HTTPBodyContainsf asserts that a specified handler returns a // body that contains a string. // -// assert.HTTPBodyContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") +// assert.HTTPBodyContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool { @@ -241,7 +283,7 @@ func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url // HTTPBodyNotContainsf asserts that a specified handler returns a // body that does not contain a string. // -// assert.HTTPBodyNotContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") +// assert.HTTPBodyNotContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool { @@ -253,7 +295,7 @@ func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, u // HTTPErrorf asserts that a specified handler returns an error status code. // -// assert.HTTPErrorf(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// assert.HTTPErrorf(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { @@ -265,7 +307,7 @@ func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, // HTTPRedirectf asserts that a specified handler returns a redirect status code. // -// assert.HTTPRedirectf(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// assert.HTTPRedirectf(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { @@ -277,7 +319,7 @@ func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url stri // HTTPStatusCodef asserts that a specified handler returns a specified status code. // -// assert.HTTPStatusCodef(t, myHandler, "GET", "/notImplemented", nil, 501, "error message %s", "formatted") +// assert.HTTPStatusCodef(t, myHandler, "GET", "/notImplemented", nil, 501, "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). func HTTPStatusCodef(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msg string, args ...interface{}) bool { @@ -289,7 +331,7 @@ func HTTPStatusCodef(t TestingT, handler http.HandlerFunc, method string, url st // HTTPSuccessf asserts that a specified handler returns a success status code. // -// assert.HTTPSuccessf(t, myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted") +// assert.HTTPSuccessf(t, myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { @@ -301,7 +343,7 @@ func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url strin // Implementsf asserts that an object is implemented by the specified interface. // -// assert.Implementsf(t, (*MyInterface)(nil), new(MyObject), "error message %s", "formatted") +// assert.Implementsf(t, (*MyInterface)(nil), new(MyObject), "error message %s", "formatted") func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -311,7 +353,7 @@ func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, ms // InDeltaf asserts that the two numerals are within delta of each other. // -// assert.InDeltaf(t, math.Pi, 22/7.0, 0.01, "error message %s", "formatted") +// assert.InDeltaf(t, math.Pi, 22/7.0, 0.01, "error message %s", "formatted") func InDeltaf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -353,9 +395,9 @@ func InEpsilonSlicef(t TestingT, expected interface{}, actual interface{}, epsil // IsDecreasingf asserts that the collection is decreasing // -// assert.IsDecreasingf(t, []int{2, 1, 0}, "error message %s", "formatted") -// assert.IsDecreasingf(t, []float{2, 1}, "error message %s", "formatted") -// assert.IsDecreasingf(t, []string{"b", "a"}, "error message %s", "formatted") +// assert.IsDecreasingf(t, []int{2, 1, 0}, "error message %s", "formatted") +// assert.IsDecreasingf(t, []float{2, 1}, "error message %s", "formatted") +// assert.IsDecreasingf(t, []string{"b", "a"}, "error message %s", "formatted") func IsDecreasingf(t TestingT, object interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -365,9 +407,9 @@ func IsDecreasingf(t TestingT, object interface{}, msg string, args ...interface // IsIncreasingf asserts that the collection is increasing // -// assert.IsIncreasingf(t, []int{1, 2, 3}, "error message %s", "formatted") -// assert.IsIncreasingf(t, []float{1, 2}, "error message %s", "formatted") -// assert.IsIncreasingf(t, []string{"a", "b"}, "error message %s", "formatted") +// assert.IsIncreasingf(t, []int{1, 2, 3}, "error message %s", "formatted") +// assert.IsIncreasingf(t, []float{1, 2}, "error message %s", "formatted") +// assert.IsIncreasingf(t, []string{"a", "b"}, "error message %s", "formatted") func IsIncreasingf(t TestingT, object interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -377,9 +419,9 @@ func IsIncreasingf(t TestingT, object interface{}, msg string, args ...interface // IsNonDecreasingf asserts that the collection is not decreasing // -// assert.IsNonDecreasingf(t, []int{1, 1, 2}, "error message %s", "formatted") -// assert.IsNonDecreasingf(t, []float{1, 2}, "error message %s", "formatted") -// assert.IsNonDecreasingf(t, []string{"a", "b"}, "error message %s", "formatted") +// assert.IsNonDecreasingf(t, []int{1, 1, 2}, "error message %s", "formatted") +// assert.IsNonDecreasingf(t, []float{1, 2}, "error message %s", "formatted") +// assert.IsNonDecreasingf(t, []string{"a", "b"}, "error message %s", "formatted") func IsNonDecreasingf(t TestingT, object interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -389,9 +431,9 @@ func IsNonDecreasingf(t TestingT, object interface{}, msg string, args ...interf // IsNonIncreasingf asserts that the collection is not increasing // -// assert.IsNonIncreasingf(t, []int{2, 1, 1}, "error message %s", "formatted") -// assert.IsNonIncreasingf(t, []float{2, 1}, "error message %s", "formatted") -// assert.IsNonIncreasingf(t, []string{"b", "a"}, "error message %s", "formatted") +// assert.IsNonIncreasingf(t, []int{2, 1, 1}, "error message %s", "formatted") +// assert.IsNonIncreasingf(t, []float{2, 1}, "error message %s", "formatted") +// assert.IsNonIncreasingf(t, []string{"b", "a"}, "error message %s", "formatted") func IsNonIncreasingf(t TestingT, object interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -409,7 +451,7 @@ func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg strin // JSONEqf asserts that two JSON strings are equivalent. // -// assert.JSONEqf(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted") +// assert.JSONEqf(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted") func JSONEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -420,7 +462,7 @@ func JSONEqf(t TestingT, expected string, actual string, msg string, args ...int // Lenf asserts that the specified object has specific length. // Lenf also fails if the object has a type that len() not accept. // -// assert.Lenf(t, mySlice, 3, "error message %s", "formatted") +// assert.Lenf(t, mySlice, 3, "error message %s", "formatted") func Lenf(t TestingT, object interface{}, length int, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -430,9 +472,9 @@ func Lenf(t TestingT, object interface{}, length int, msg string, args ...interf // Lessf asserts that the first element is less than the second // -// assert.Lessf(t, 1, 2, "error message %s", "formatted") -// assert.Lessf(t, float64(1), float64(2), "error message %s", "formatted") -// assert.Lessf(t, "a", "b", "error message %s", "formatted") +// assert.Lessf(t, 1, 2, "error message %s", "formatted") +// assert.Lessf(t, float64(1), float64(2), "error message %s", "formatted") +// assert.Lessf(t, "a", "b", "error message %s", "formatted") func Lessf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -442,10 +484,10 @@ func Lessf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...inter // LessOrEqualf asserts that the first element is less than or equal to the second // -// assert.LessOrEqualf(t, 1, 2, "error message %s", "formatted") -// assert.LessOrEqualf(t, 2, 2, "error message %s", "formatted") -// assert.LessOrEqualf(t, "a", "b", "error message %s", "formatted") -// assert.LessOrEqualf(t, "b", "b", "error message %s", "formatted") +// assert.LessOrEqualf(t, 1, 2, "error message %s", "formatted") +// assert.LessOrEqualf(t, 2, 2, "error message %s", "formatted") +// assert.LessOrEqualf(t, "a", "b", "error message %s", "formatted") +// assert.LessOrEqualf(t, "b", "b", "error message %s", "formatted") func LessOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -455,8 +497,8 @@ func LessOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args . // Negativef asserts that the specified element is negative // -// assert.Negativef(t, -1, "error message %s", "formatted") -// assert.Negativef(t, -1.23, "error message %s", "formatted") +// assert.Negativef(t, -1, "error message %s", "formatted") +// assert.Negativef(t, -1.23, "error message %s", "formatted") func Negativef(t TestingT, e interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -467,7 +509,7 @@ func Negativef(t TestingT, e interface{}, msg string, args ...interface{}) bool // Neverf asserts that the given condition doesn't satisfy in waitFor time, // periodically checking the target function each tick. // -// assert.Neverf(t, func() bool { return false; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") +// assert.Neverf(t, func() bool { return false; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") func Neverf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -477,7 +519,7 @@ func Neverf(t TestingT, condition func() bool, waitFor time.Duration, tick time. // Nilf asserts that the specified object is nil. // -// assert.Nilf(t, err, "error message %s", "formatted") +// assert.Nilf(t, err, "error message %s", "formatted") func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -496,10 +538,10 @@ func NoDirExistsf(t TestingT, path string, msg string, args ...interface{}) bool // NoErrorf asserts that a function returned no error (i.e. `nil`). // -// actualObj, err := SomeFunction() -// if assert.NoErrorf(t, err, "error message %s", "formatted") { -// assert.Equal(t, expectedObj, actualObj) -// } +// actualObj, err := SomeFunction() +// if assert.NoErrorf(t, err, "error message %s", "formatted") { +// assert.Equal(t, expectedObj, actualObj) +// } func NoErrorf(t TestingT, err error, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -519,9 +561,9 @@ func NoFileExistsf(t TestingT, path string, msg string, args ...interface{}) boo // NotContainsf asserts that the specified string, list(array, slice...) or map does NOT contain the // specified substring or element. // -// assert.NotContainsf(t, "Hello World", "Earth", "error message %s", "formatted") -// assert.NotContainsf(t, ["Hello", "World"], "Earth", "error message %s", "formatted") -// assert.NotContainsf(t, {"Hello": "World"}, "Earth", "error message %s", "formatted") +// assert.NotContainsf(t, "Hello World", "Earth", "error message %s", "formatted") +// assert.NotContainsf(t, ["Hello", "World"], "Earth", "error message %s", "formatted") +// assert.NotContainsf(t, {"Hello": "World"}, "Earth", "error message %s", "formatted") func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -532,9 +574,9 @@ func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, a // NotEmptyf asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either // a slice or a channel with len == 0. // -// if assert.NotEmptyf(t, obj, "error message %s", "formatted") { -// assert.Equal(t, "two", obj[1]) -// } +// if assert.NotEmptyf(t, obj, "error message %s", "formatted") { +// assert.Equal(t, "two", obj[1]) +// } func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -544,7 +586,7 @@ func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) // NotEqualf asserts that the specified values are NOT equal. // -// assert.NotEqualf(t, obj1, obj2, "error message %s", "formatted") +// assert.NotEqualf(t, obj1, obj2, "error message %s", "formatted") // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). @@ -557,7 +599,7 @@ func NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string, // NotEqualValuesf asserts that two objects are not equal even when converted to the same type // -// assert.NotEqualValuesf(t, obj1, obj2, "error message %s", "formatted") +// assert.NotEqualValuesf(t, obj1, obj2, "error message %s", "formatted") func NotEqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -576,7 +618,7 @@ func NotErrorIsf(t TestingT, err error, target error, msg string, args ...interf // NotNilf asserts that the specified object is not nil. // -// assert.NotNilf(t, err, "error message %s", "formatted") +// assert.NotNilf(t, err, "error message %s", "formatted") func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -586,7 +628,7 @@ func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) bo // NotPanicsf asserts that the code inside the specified PanicTestFunc does NOT panic. // -// assert.NotPanicsf(t, func(){ RemainCalm() }, "error message %s", "formatted") +// assert.NotPanicsf(t, func(){ RemainCalm() }, "error message %s", "formatted") func NotPanicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -596,8 +638,8 @@ func NotPanicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bo // NotRegexpf asserts that a specified regexp does not match a string. // -// assert.NotRegexpf(t, regexp.MustCompile("starts"), "it's starting", "error message %s", "formatted") -// assert.NotRegexpf(t, "^start", "it's not starting", "error message %s", "formatted") +// assert.NotRegexpf(t, regexp.MustCompile("starts"), "it's starting", "error message %s", "formatted") +// assert.NotRegexpf(t, "^start", "it's not starting", "error message %s", "formatted") func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -607,7 +649,7 @@ func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args .. // NotSamef asserts that two pointers do not reference the same object. // -// assert.NotSamef(t, ptr1, ptr2, "error message %s", "formatted") +// assert.NotSamef(t, ptr1, ptr2, "error message %s", "formatted") // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. @@ -621,7 +663,7 @@ func NotSamef(t TestingT, expected interface{}, actual interface{}, msg string, // NotSubsetf asserts that the specified list(array, slice...) contains not all // elements given in the specified subset(array, slice...). // -// assert.NotSubsetf(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted") +// assert.NotSubsetf(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted") func NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -639,7 +681,7 @@ func NotZerof(t TestingT, i interface{}, msg string, args ...interface{}) bool { // Panicsf asserts that the code inside the specified PanicTestFunc panics. // -// assert.Panicsf(t, func(){ GoCrazy() }, "error message %s", "formatted") +// assert.Panicsf(t, func(){ GoCrazy() }, "error message %s", "formatted") func Panicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -651,7 +693,7 @@ func Panicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool // panics, and that the recovered panic value is an error that satisfies the // EqualError comparison. // -// assert.PanicsWithErrorf(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") +// assert.PanicsWithErrorf(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") func PanicsWithErrorf(t TestingT, errString string, f PanicTestFunc, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -662,7 +704,7 @@ func PanicsWithErrorf(t TestingT, errString string, f PanicTestFunc, msg string, // PanicsWithValuef asserts that the code inside the specified PanicTestFunc panics, and that // the recovered panic value equals the expected panic value. // -// assert.PanicsWithValuef(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") +// assert.PanicsWithValuef(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") func PanicsWithValuef(t TestingT, expected interface{}, f PanicTestFunc, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -672,8 +714,8 @@ func PanicsWithValuef(t TestingT, expected interface{}, f PanicTestFunc, msg str // Positivef asserts that the specified element is positive // -// assert.Positivef(t, 1, "error message %s", "formatted") -// assert.Positivef(t, 1.23, "error message %s", "formatted") +// assert.Positivef(t, 1, "error message %s", "formatted") +// assert.Positivef(t, 1.23, "error message %s", "formatted") func Positivef(t TestingT, e interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -683,8 +725,8 @@ func Positivef(t TestingT, e interface{}, msg string, args ...interface{}) bool // Regexpf asserts that a specified regexp matches a string. // -// assert.Regexpf(t, regexp.MustCompile("start"), "it's starting", "error message %s", "formatted") -// assert.Regexpf(t, "start...$", "it's not starting", "error message %s", "formatted") +// assert.Regexpf(t, regexp.MustCompile("start"), "it's starting", "error message %s", "formatted") +// assert.Regexpf(t, "start...$", "it's not starting", "error message %s", "formatted") func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -694,7 +736,7 @@ func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...in // Samef asserts that two pointers reference the same object. // -// assert.Samef(t, ptr1, ptr2, "error message %s", "formatted") +// assert.Samef(t, ptr1, ptr2, "error message %s", "formatted") // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. @@ -708,7 +750,7 @@ func Samef(t TestingT, expected interface{}, actual interface{}, msg string, arg // Subsetf asserts that the specified list(array, slice...) contains all // elements given in the specified subset(array, slice...). // -// assert.Subsetf(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted") +// assert.Subsetf(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted") func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -718,7 +760,7 @@ func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args // Truef asserts that the specified value is true. // -// assert.Truef(t, myBool, "error message %s", "formatted") +// assert.Truef(t, myBool, "error message %s", "formatted") func Truef(t TestingT, value bool, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -728,7 +770,7 @@ func Truef(t TestingT, value bool, msg string, args ...interface{}) bool { // WithinDurationf asserts that the two times are within duration delta of each other. // -// assert.WithinDurationf(t, time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted") +// assert.WithinDurationf(t, time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted") func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -738,7 +780,7 @@ func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta tim // WithinRangef asserts that a time is within a time range (inclusive). // -// assert.WithinRangef(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), "error message %s", "formatted") +// assert.WithinRangef(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), "error message %s", "formatted") func WithinRangef(t TestingT, actual time.Time, start time.Time, end time.Time, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() diff --git a/vendor/github.com/stretchr/testify/assert/assertion_forward.go b/vendor/github.com/stretchr/testify/assert/assertion_forward.go index 339515b8bf..b1d94aec53 100644 --- a/vendor/github.com/stretchr/testify/assert/assertion_forward.go +++ b/vendor/github.com/stretchr/testify/assert/assertion_forward.go @@ -30,9 +30,9 @@ func (a *Assertions) Conditionf(comp Comparison, msg string, args ...interface{} // Contains asserts that the specified string, list(array, slice...) or map contains the // specified substring or element. // -// a.Contains("Hello World", "World") -// a.Contains(["Hello", "World"], "World") -// a.Contains({"Hello": "World"}, "Hello") +// a.Contains("Hello World", "World") +// a.Contains(["Hello", "World"], "World") +// a.Contains({"Hello": "World"}, "Hello") func (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -43,9 +43,9 @@ func (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs .. // Containsf asserts that the specified string, list(array, slice...) or map contains the // specified substring or element. // -// a.Containsf("Hello World", "World", "error message %s", "formatted") -// a.Containsf(["Hello", "World"], "World", "error message %s", "formatted") -// a.Containsf({"Hello": "World"}, "Hello", "error message %s", "formatted") +// a.Containsf("Hello World", "World", "error message %s", "formatted") +// a.Containsf(["Hello", "World"], "World", "error message %s", "formatted") +// a.Containsf({"Hello": "World"}, "Hello", "error message %s", "formatted") func (a *Assertions) Containsf(s interface{}, contains interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -98,7 +98,7 @@ func (a *Assertions) ElementsMatchf(listA interface{}, listB interface{}, msg st // Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either // a slice or a channel with len == 0. // -// a.Empty(obj) +// a.Empty(obj) func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -109,7 +109,7 @@ func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) bool { // Emptyf asserts that the specified object is empty. I.e. nil, "", false, 0 or either // a slice or a channel with len == 0. // -// a.Emptyf(obj, "error message %s", "formatted") +// a.Emptyf(obj, "error message %s", "formatted") func (a *Assertions) Emptyf(object interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -119,7 +119,7 @@ func (a *Assertions) Emptyf(object interface{}, msg string, args ...interface{}) // Equal asserts that two objects are equal. // -// a.Equal(123, 123) +// a.Equal(123, 123) // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). Function equality @@ -134,8 +134,8 @@ func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs // EqualError asserts that a function returned an error (i.e. not `nil`) // and that it is equal to the provided error. // -// actualObj, err := SomeFunction() -// a.EqualError(err, expectedErrorString) +// actualObj, err := SomeFunction() +// a.EqualError(err, expectedErrorString) func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -146,8 +146,8 @@ func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ... // EqualErrorf asserts that a function returned an error (i.e. not `nil`) // and that it is equal to the provided error. // -// actualObj, err := SomeFunction() -// a.EqualErrorf(err, expectedErrorString, "error message %s", "formatted") +// actualObj, err := SomeFunction() +// a.EqualErrorf(err, expectedErrorString, "error message %s", "formatted") func (a *Assertions) EqualErrorf(theError error, errString string, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -155,10 +155,44 @@ func (a *Assertions) EqualErrorf(theError error, errString string, msg string, a return EqualErrorf(a.t, theError, errString, msg, args...) } +// EqualExportedValues asserts that the types of two objects are equal and their public +// fields are also equal. This is useful for comparing structs that have private fields +// that could potentially differ. +// +// type S struct { +// Exported int +// notExported int +// } +// a.EqualExportedValues(S{1, 2}, S{1, 3}) => true +// a.EqualExportedValues(S{1, 2}, S{2, 3}) => false +func (a *Assertions) EqualExportedValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return EqualExportedValues(a.t, expected, actual, msgAndArgs...) +} + +// EqualExportedValuesf asserts that the types of two objects are equal and their public +// fields are also equal. This is useful for comparing structs that have private fields +// that could potentially differ. +// +// type S struct { +// Exported int +// notExported int +// } +// a.EqualExportedValuesf(S{1, 2}, S{1, 3}, "error message %s", "formatted") => true +// a.EqualExportedValuesf(S{1, 2}, S{2, 3}, "error message %s", "formatted") => false +func (a *Assertions) EqualExportedValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return EqualExportedValuesf(a.t, expected, actual, msg, args...) +} + // EqualValues asserts that two objects are equal or convertable to the same types // and equal. // -// a.EqualValues(uint32(123), int32(123)) +// a.EqualValues(uint32(123), int32(123)) func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -169,7 +203,7 @@ func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAn // EqualValuesf asserts that two objects are equal or convertable to the same types // and equal. // -// a.EqualValuesf(uint32(123), int32(123), "error message %s", "formatted") +// a.EqualValuesf(uint32(123), int32(123), "error message %s", "formatted") func (a *Assertions) EqualValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -179,7 +213,7 @@ func (a *Assertions) EqualValuesf(expected interface{}, actual interface{}, msg // Equalf asserts that two objects are equal. // -// a.Equalf(123, 123, "error message %s", "formatted") +// a.Equalf(123, 123, "error message %s", "formatted") // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). Function equality @@ -193,10 +227,10 @@ func (a *Assertions) Equalf(expected interface{}, actual interface{}, msg string // Error asserts that a function returned an error (i.e. not `nil`). // -// actualObj, err := SomeFunction() -// if a.Error(err) { -// assert.Equal(t, expectedError, err) -// } +// actualObj, err := SomeFunction() +// if a.Error(err) { +// assert.Equal(t, expectedError, err) +// } func (a *Assertions) Error(err error, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -225,8 +259,8 @@ func (a *Assertions) ErrorAsf(err error, target interface{}, msg string, args .. // ErrorContains asserts that a function returned an error (i.e. not `nil`) // and that the error contains the specified substring. // -// actualObj, err := SomeFunction() -// a.ErrorContains(err, expectedErrorSubString) +// actualObj, err := SomeFunction() +// a.ErrorContains(err, expectedErrorSubString) func (a *Assertions) ErrorContains(theError error, contains string, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -237,8 +271,8 @@ func (a *Assertions) ErrorContains(theError error, contains string, msgAndArgs . // ErrorContainsf asserts that a function returned an error (i.e. not `nil`) // and that the error contains the specified substring. // -// actualObj, err := SomeFunction() -// a.ErrorContainsf(err, expectedErrorSubString, "error message %s", "formatted") +// actualObj, err := SomeFunction() +// a.ErrorContainsf(err, expectedErrorSubString, "error message %s", "formatted") func (a *Assertions) ErrorContainsf(theError error, contains string, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -266,10 +300,10 @@ func (a *Assertions) ErrorIsf(err error, target error, msg string, args ...inter // Errorf asserts that a function returned an error (i.e. not `nil`). // -// actualObj, err := SomeFunction() -// if a.Errorf(err, "error message %s", "formatted") { -// assert.Equal(t, expectedErrorf, err) -// } +// actualObj, err := SomeFunction() +// if a.Errorf(err, "error message %s", "formatted") { +// assert.Equal(t, expectedErrorf, err) +// } func (a *Assertions) Errorf(err error, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -280,7 +314,7 @@ func (a *Assertions) Errorf(err error, msg string, args ...interface{}) bool { // Eventually asserts that given condition will be met in waitFor time, // periodically checking target function each tick. // -// a.Eventually(func() bool { return true; }, time.Second, 10*time.Millisecond) +// a.Eventually(func() bool { return true; }, time.Second, 10*time.Millisecond) func (a *Assertions) Eventually(condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -288,10 +322,60 @@ func (a *Assertions) Eventually(condition func() bool, waitFor time.Duration, ti return Eventually(a.t, condition, waitFor, tick, msgAndArgs...) } +// EventuallyWithT asserts that given condition will be met in waitFor time, +// periodically checking target function each tick. In contrast to Eventually, +// it supplies a CollectT to the condition function, so that the condition +// function can use the CollectT to call other assertions. +// The condition is considered "met" if no errors are raised in a tick. +// The supplied CollectT collects all errors from one tick (if there are any). +// If the condition is not met before waitFor, the collected errors of +// the last tick are copied to t. +// +// externalValue := false +// go func() { +// time.Sleep(8*time.Second) +// externalValue = true +// }() +// a.EventuallyWithT(func(c *assert.CollectT) { +// // add assertions as needed; any assertion failure will fail the current tick +// assert.True(c, externalValue, "expected 'externalValue' to be true") +// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") +func (a *Assertions) EventuallyWithT(condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return EventuallyWithT(a.t, condition, waitFor, tick, msgAndArgs...) +} + +// EventuallyWithTf asserts that given condition will be met in waitFor time, +// periodically checking target function each tick. In contrast to Eventually, +// it supplies a CollectT to the condition function, so that the condition +// function can use the CollectT to call other assertions. +// The condition is considered "met" if no errors are raised in a tick. +// The supplied CollectT collects all errors from one tick (if there are any). +// If the condition is not met before waitFor, the collected errors of +// the last tick are copied to t. +// +// externalValue := false +// go func() { +// time.Sleep(8*time.Second) +// externalValue = true +// }() +// a.EventuallyWithTf(func(c *assert.CollectT, "error message %s", "formatted") { +// // add assertions as needed; any assertion failure will fail the current tick +// assert.True(c, externalValue, "expected 'externalValue' to be true") +// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") +func (a *Assertions) EventuallyWithTf(condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return EventuallyWithTf(a.t, condition, waitFor, tick, msg, args...) +} + // Eventuallyf asserts that given condition will be met in waitFor time, // periodically checking target function each tick. // -// a.Eventuallyf(func() bool { return true; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") +// a.Eventuallyf(func() bool { return true; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") func (a *Assertions) Eventuallyf(condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -301,7 +385,7 @@ func (a *Assertions) Eventuallyf(condition func() bool, waitFor time.Duration, t // Exactly asserts that two objects are equal in value and type. // -// a.Exactly(int32(123), int64(123)) +// a.Exactly(int32(123), int64(123)) func (a *Assertions) Exactly(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -311,7 +395,7 @@ func (a *Assertions) Exactly(expected interface{}, actual interface{}, msgAndArg // Exactlyf asserts that two objects are equal in value and type. // -// a.Exactlyf(int32(123), int64(123), "error message %s", "formatted") +// a.Exactlyf(int32(123), int64(123), "error message %s", "formatted") func (a *Assertions) Exactlyf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -353,7 +437,7 @@ func (a *Assertions) Failf(failureMessage string, msg string, args ...interface{ // False asserts that the specified value is false. // -// a.False(myBool) +// a.False(myBool) func (a *Assertions) False(value bool, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -363,7 +447,7 @@ func (a *Assertions) False(value bool, msgAndArgs ...interface{}) bool { // Falsef asserts that the specified value is false. // -// a.Falsef(myBool, "error message %s", "formatted") +// a.Falsef(myBool, "error message %s", "formatted") func (a *Assertions) Falsef(value bool, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -391,9 +475,9 @@ func (a *Assertions) FileExistsf(path string, msg string, args ...interface{}) b // Greater asserts that the first element is greater than the second // -// a.Greater(2, 1) -// a.Greater(float64(2), float64(1)) -// a.Greater("b", "a") +// a.Greater(2, 1) +// a.Greater(float64(2), float64(1)) +// a.Greater("b", "a") func (a *Assertions) Greater(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -403,10 +487,10 @@ func (a *Assertions) Greater(e1 interface{}, e2 interface{}, msgAndArgs ...inter // GreaterOrEqual asserts that the first element is greater than or equal to the second // -// a.GreaterOrEqual(2, 1) -// a.GreaterOrEqual(2, 2) -// a.GreaterOrEqual("b", "a") -// a.GreaterOrEqual("b", "b") +// a.GreaterOrEqual(2, 1) +// a.GreaterOrEqual(2, 2) +// a.GreaterOrEqual("b", "a") +// a.GreaterOrEqual("b", "b") func (a *Assertions) GreaterOrEqual(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -416,10 +500,10 @@ func (a *Assertions) GreaterOrEqual(e1 interface{}, e2 interface{}, msgAndArgs . // GreaterOrEqualf asserts that the first element is greater than or equal to the second // -// a.GreaterOrEqualf(2, 1, "error message %s", "formatted") -// a.GreaterOrEqualf(2, 2, "error message %s", "formatted") -// a.GreaterOrEqualf("b", "a", "error message %s", "formatted") -// a.GreaterOrEqualf("b", "b", "error message %s", "formatted") +// a.GreaterOrEqualf(2, 1, "error message %s", "formatted") +// a.GreaterOrEqualf(2, 2, "error message %s", "formatted") +// a.GreaterOrEqualf("b", "a", "error message %s", "formatted") +// a.GreaterOrEqualf("b", "b", "error message %s", "formatted") func (a *Assertions) GreaterOrEqualf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -429,9 +513,9 @@ func (a *Assertions) GreaterOrEqualf(e1 interface{}, e2 interface{}, msg string, // Greaterf asserts that the first element is greater than the second // -// a.Greaterf(2, 1, "error message %s", "formatted") -// a.Greaterf(float64(2), float64(1), "error message %s", "formatted") -// a.Greaterf("b", "a", "error message %s", "formatted") +// a.Greaterf(2, 1, "error message %s", "formatted") +// a.Greaterf(float64(2), float64(1), "error message %s", "formatted") +// a.Greaterf("b", "a", "error message %s", "formatted") func (a *Assertions) Greaterf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -442,7 +526,7 @@ func (a *Assertions) Greaterf(e1 interface{}, e2 interface{}, msg string, args . // HTTPBodyContains asserts that a specified handler returns a // body that contains a string. // -// a.HTTPBodyContains(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") +// a.HTTPBodyContains(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool { @@ -455,7 +539,7 @@ func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, u // HTTPBodyContainsf asserts that a specified handler returns a // body that contains a string. // -// a.HTTPBodyContainsf(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") +// a.HTTPBodyContainsf(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPBodyContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool { @@ -468,7 +552,7 @@ func (a *Assertions) HTTPBodyContainsf(handler http.HandlerFunc, method string, // HTTPBodyNotContains asserts that a specified handler returns a // body that does not contain a string. // -// a.HTTPBodyNotContains(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") +// a.HTTPBodyNotContains(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool { @@ -481,7 +565,7 @@ func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string // HTTPBodyNotContainsf asserts that a specified handler returns a // body that does not contain a string. // -// a.HTTPBodyNotContainsf(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") +// a.HTTPBodyNotContainsf(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPBodyNotContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool { @@ -493,7 +577,7 @@ func (a *Assertions) HTTPBodyNotContainsf(handler http.HandlerFunc, method strin // HTTPError asserts that a specified handler returns an error status code. // -// a.HTTPError(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// a.HTTPError(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool { @@ -505,7 +589,7 @@ func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url stri // HTTPErrorf asserts that a specified handler returns an error status code. // -// a.HTTPErrorf(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// a.HTTPErrorf(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPErrorf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { @@ -517,7 +601,7 @@ func (a *Assertions) HTTPErrorf(handler http.HandlerFunc, method string, url str // HTTPRedirect asserts that a specified handler returns a redirect status code. // -// a.HTTPRedirect(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// a.HTTPRedirect(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool { @@ -529,7 +613,7 @@ func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url s // HTTPRedirectf asserts that a specified handler returns a redirect status code. // -// a.HTTPRedirectf(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// a.HTTPRedirectf(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPRedirectf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { @@ -541,7 +625,7 @@ func (a *Assertions) HTTPRedirectf(handler http.HandlerFunc, method string, url // HTTPStatusCode asserts that a specified handler returns a specified status code. // -// a.HTTPStatusCode(myHandler, "GET", "/notImplemented", nil, 501) +// a.HTTPStatusCode(myHandler, "GET", "/notImplemented", nil, 501) // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPStatusCode(handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msgAndArgs ...interface{}) bool { @@ -553,7 +637,7 @@ func (a *Assertions) HTTPStatusCode(handler http.HandlerFunc, method string, url // HTTPStatusCodef asserts that a specified handler returns a specified status code. // -// a.HTTPStatusCodef(myHandler, "GET", "/notImplemented", nil, 501, "error message %s", "formatted") +// a.HTTPStatusCodef(myHandler, "GET", "/notImplemented", nil, 501, "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPStatusCodef(handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msg string, args ...interface{}) bool { @@ -565,7 +649,7 @@ func (a *Assertions) HTTPStatusCodef(handler http.HandlerFunc, method string, ur // HTTPSuccess asserts that a specified handler returns a success status code. // -// a.HTTPSuccess(myHandler, "POST", "http://www.google.com", nil) +// a.HTTPSuccess(myHandler, "POST", "http://www.google.com", nil) // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool { @@ -577,7 +661,7 @@ func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url st // HTTPSuccessf asserts that a specified handler returns a success status code. // -// a.HTTPSuccessf(myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted") +// a.HTTPSuccessf(myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPSuccessf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { @@ -589,7 +673,7 @@ func (a *Assertions) HTTPSuccessf(handler http.HandlerFunc, method string, url s // Implements asserts that an object is implemented by the specified interface. // -// a.Implements((*MyInterface)(nil), new(MyObject)) +// a.Implements((*MyInterface)(nil), new(MyObject)) func (a *Assertions) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -599,7 +683,7 @@ func (a *Assertions) Implements(interfaceObject interface{}, object interface{}, // Implementsf asserts that an object is implemented by the specified interface. // -// a.Implementsf((*MyInterface)(nil), new(MyObject), "error message %s", "formatted") +// a.Implementsf((*MyInterface)(nil), new(MyObject), "error message %s", "formatted") func (a *Assertions) Implementsf(interfaceObject interface{}, object interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -609,7 +693,7 @@ func (a *Assertions) Implementsf(interfaceObject interface{}, object interface{} // InDelta asserts that the two numerals are within delta of each other. // -// a.InDelta(math.Pi, 22/7.0, 0.01) +// a.InDelta(math.Pi, 22/7.0, 0.01) func (a *Assertions) InDelta(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -651,7 +735,7 @@ func (a *Assertions) InDeltaSlicef(expected interface{}, actual interface{}, del // InDeltaf asserts that the two numerals are within delta of each other. // -// a.InDeltaf(math.Pi, 22/7.0, 0.01, "error message %s", "formatted") +// a.InDeltaf(math.Pi, 22/7.0, 0.01, "error message %s", "formatted") func (a *Assertions) InDeltaf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -693,9 +777,9 @@ func (a *Assertions) InEpsilonf(expected interface{}, actual interface{}, epsilo // IsDecreasing asserts that the collection is decreasing // -// a.IsDecreasing([]int{2, 1, 0}) -// a.IsDecreasing([]float{2, 1}) -// a.IsDecreasing([]string{"b", "a"}) +// a.IsDecreasing([]int{2, 1, 0}) +// a.IsDecreasing([]float{2, 1}) +// a.IsDecreasing([]string{"b", "a"}) func (a *Assertions) IsDecreasing(object interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -705,9 +789,9 @@ func (a *Assertions) IsDecreasing(object interface{}, msgAndArgs ...interface{}) // IsDecreasingf asserts that the collection is decreasing // -// a.IsDecreasingf([]int{2, 1, 0}, "error message %s", "formatted") -// a.IsDecreasingf([]float{2, 1}, "error message %s", "formatted") -// a.IsDecreasingf([]string{"b", "a"}, "error message %s", "formatted") +// a.IsDecreasingf([]int{2, 1, 0}, "error message %s", "formatted") +// a.IsDecreasingf([]float{2, 1}, "error message %s", "formatted") +// a.IsDecreasingf([]string{"b", "a"}, "error message %s", "formatted") func (a *Assertions) IsDecreasingf(object interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -717,9 +801,9 @@ func (a *Assertions) IsDecreasingf(object interface{}, msg string, args ...inter // IsIncreasing asserts that the collection is increasing // -// a.IsIncreasing([]int{1, 2, 3}) -// a.IsIncreasing([]float{1, 2}) -// a.IsIncreasing([]string{"a", "b"}) +// a.IsIncreasing([]int{1, 2, 3}) +// a.IsIncreasing([]float{1, 2}) +// a.IsIncreasing([]string{"a", "b"}) func (a *Assertions) IsIncreasing(object interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -729,9 +813,9 @@ func (a *Assertions) IsIncreasing(object interface{}, msgAndArgs ...interface{}) // IsIncreasingf asserts that the collection is increasing // -// a.IsIncreasingf([]int{1, 2, 3}, "error message %s", "formatted") -// a.IsIncreasingf([]float{1, 2}, "error message %s", "formatted") -// a.IsIncreasingf([]string{"a", "b"}, "error message %s", "formatted") +// a.IsIncreasingf([]int{1, 2, 3}, "error message %s", "formatted") +// a.IsIncreasingf([]float{1, 2}, "error message %s", "formatted") +// a.IsIncreasingf([]string{"a", "b"}, "error message %s", "formatted") func (a *Assertions) IsIncreasingf(object interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -741,9 +825,9 @@ func (a *Assertions) IsIncreasingf(object interface{}, msg string, args ...inter // IsNonDecreasing asserts that the collection is not decreasing // -// a.IsNonDecreasing([]int{1, 1, 2}) -// a.IsNonDecreasing([]float{1, 2}) -// a.IsNonDecreasing([]string{"a", "b"}) +// a.IsNonDecreasing([]int{1, 1, 2}) +// a.IsNonDecreasing([]float{1, 2}) +// a.IsNonDecreasing([]string{"a", "b"}) func (a *Assertions) IsNonDecreasing(object interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -753,9 +837,9 @@ func (a *Assertions) IsNonDecreasing(object interface{}, msgAndArgs ...interface // IsNonDecreasingf asserts that the collection is not decreasing // -// a.IsNonDecreasingf([]int{1, 1, 2}, "error message %s", "formatted") -// a.IsNonDecreasingf([]float{1, 2}, "error message %s", "formatted") -// a.IsNonDecreasingf([]string{"a", "b"}, "error message %s", "formatted") +// a.IsNonDecreasingf([]int{1, 1, 2}, "error message %s", "formatted") +// a.IsNonDecreasingf([]float{1, 2}, "error message %s", "formatted") +// a.IsNonDecreasingf([]string{"a", "b"}, "error message %s", "formatted") func (a *Assertions) IsNonDecreasingf(object interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -765,9 +849,9 @@ func (a *Assertions) IsNonDecreasingf(object interface{}, msg string, args ...in // IsNonIncreasing asserts that the collection is not increasing // -// a.IsNonIncreasing([]int{2, 1, 1}) -// a.IsNonIncreasing([]float{2, 1}) -// a.IsNonIncreasing([]string{"b", "a"}) +// a.IsNonIncreasing([]int{2, 1, 1}) +// a.IsNonIncreasing([]float{2, 1}) +// a.IsNonIncreasing([]string{"b", "a"}) func (a *Assertions) IsNonIncreasing(object interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -777,9 +861,9 @@ func (a *Assertions) IsNonIncreasing(object interface{}, msgAndArgs ...interface // IsNonIncreasingf asserts that the collection is not increasing // -// a.IsNonIncreasingf([]int{2, 1, 1}, "error message %s", "formatted") -// a.IsNonIncreasingf([]float{2, 1}, "error message %s", "formatted") -// a.IsNonIncreasingf([]string{"b", "a"}, "error message %s", "formatted") +// a.IsNonIncreasingf([]int{2, 1, 1}, "error message %s", "formatted") +// a.IsNonIncreasingf([]float{2, 1}, "error message %s", "formatted") +// a.IsNonIncreasingf([]string{"b", "a"}, "error message %s", "formatted") func (a *Assertions) IsNonIncreasingf(object interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -805,7 +889,7 @@ func (a *Assertions) IsTypef(expectedType interface{}, object interface{}, msg s // JSONEq asserts that two JSON strings are equivalent. // -// a.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) +// a.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -815,7 +899,7 @@ func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interf // JSONEqf asserts that two JSON strings are equivalent. // -// a.JSONEqf(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted") +// a.JSONEqf(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted") func (a *Assertions) JSONEqf(expected string, actual string, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -826,7 +910,7 @@ func (a *Assertions) JSONEqf(expected string, actual string, msg string, args .. // Len asserts that the specified object has specific length. // Len also fails if the object has a type that len() not accept. // -// a.Len(mySlice, 3) +// a.Len(mySlice, 3) func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -837,7 +921,7 @@ func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface // Lenf asserts that the specified object has specific length. // Lenf also fails if the object has a type that len() not accept. // -// a.Lenf(mySlice, 3, "error message %s", "formatted") +// a.Lenf(mySlice, 3, "error message %s", "formatted") func (a *Assertions) Lenf(object interface{}, length int, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -847,9 +931,9 @@ func (a *Assertions) Lenf(object interface{}, length int, msg string, args ...in // Less asserts that the first element is less than the second // -// a.Less(1, 2) -// a.Less(float64(1), float64(2)) -// a.Less("a", "b") +// a.Less(1, 2) +// a.Less(float64(1), float64(2)) +// a.Less("a", "b") func (a *Assertions) Less(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -859,10 +943,10 @@ func (a *Assertions) Less(e1 interface{}, e2 interface{}, msgAndArgs ...interfac // LessOrEqual asserts that the first element is less than or equal to the second // -// a.LessOrEqual(1, 2) -// a.LessOrEqual(2, 2) -// a.LessOrEqual("a", "b") -// a.LessOrEqual("b", "b") +// a.LessOrEqual(1, 2) +// a.LessOrEqual(2, 2) +// a.LessOrEqual("a", "b") +// a.LessOrEqual("b", "b") func (a *Assertions) LessOrEqual(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -872,10 +956,10 @@ func (a *Assertions) LessOrEqual(e1 interface{}, e2 interface{}, msgAndArgs ...i // LessOrEqualf asserts that the first element is less than or equal to the second // -// a.LessOrEqualf(1, 2, "error message %s", "formatted") -// a.LessOrEqualf(2, 2, "error message %s", "formatted") -// a.LessOrEqualf("a", "b", "error message %s", "formatted") -// a.LessOrEqualf("b", "b", "error message %s", "formatted") +// a.LessOrEqualf(1, 2, "error message %s", "formatted") +// a.LessOrEqualf(2, 2, "error message %s", "formatted") +// a.LessOrEqualf("a", "b", "error message %s", "formatted") +// a.LessOrEqualf("b", "b", "error message %s", "formatted") func (a *Assertions) LessOrEqualf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -885,9 +969,9 @@ func (a *Assertions) LessOrEqualf(e1 interface{}, e2 interface{}, msg string, ar // Lessf asserts that the first element is less than the second // -// a.Lessf(1, 2, "error message %s", "formatted") -// a.Lessf(float64(1), float64(2), "error message %s", "formatted") -// a.Lessf("a", "b", "error message %s", "formatted") +// a.Lessf(1, 2, "error message %s", "formatted") +// a.Lessf(float64(1), float64(2), "error message %s", "formatted") +// a.Lessf("a", "b", "error message %s", "formatted") func (a *Assertions) Lessf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -897,8 +981,8 @@ func (a *Assertions) Lessf(e1 interface{}, e2 interface{}, msg string, args ...i // Negative asserts that the specified element is negative // -// a.Negative(-1) -// a.Negative(-1.23) +// a.Negative(-1) +// a.Negative(-1.23) func (a *Assertions) Negative(e interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -908,8 +992,8 @@ func (a *Assertions) Negative(e interface{}, msgAndArgs ...interface{}) bool { // Negativef asserts that the specified element is negative // -// a.Negativef(-1, "error message %s", "formatted") -// a.Negativef(-1.23, "error message %s", "formatted") +// a.Negativef(-1, "error message %s", "formatted") +// a.Negativef(-1.23, "error message %s", "formatted") func (a *Assertions) Negativef(e interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -920,7 +1004,7 @@ func (a *Assertions) Negativef(e interface{}, msg string, args ...interface{}) b // Never asserts that the given condition doesn't satisfy in waitFor time, // periodically checking the target function each tick. // -// a.Never(func() bool { return false; }, time.Second, 10*time.Millisecond) +// a.Never(func() bool { return false; }, time.Second, 10*time.Millisecond) func (a *Assertions) Never(condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -931,7 +1015,7 @@ func (a *Assertions) Never(condition func() bool, waitFor time.Duration, tick ti // Neverf asserts that the given condition doesn't satisfy in waitFor time, // periodically checking the target function each tick. // -// a.Neverf(func() bool { return false; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") +// a.Neverf(func() bool { return false; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") func (a *Assertions) Neverf(condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -941,7 +1025,7 @@ func (a *Assertions) Neverf(condition func() bool, waitFor time.Duration, tick t // Nil asserts that the specified object is nil. // -// a.Nil(err) +// a.Nil(err) func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -951,7 +1035,7 @@ func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) bool { // Nilf asserts that the specified object is nil. // -// a.Nilf(err, "error message %s", "formatted") +// a.Nilf(err, "error message %s", "formatted") func (a *Assertions) Nilf(object interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -979,10 +1063,10 @@ func (a *Assertions) NoDirExistsf(path string, msg string, args ...interface{}) // NoError asserts that a function returned no error (i.e. `nil`). // -// actualObj, err := SomeFunction() -// if a.NoError(err) { -// assert.Equal(t, expectedObj, actualObj) -// } +// actualObj, err := SomeFunction() +// if a.NoError(err) { +// assert.Equal(t, expectedObj, actualObj) +// } func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -992,10 +1076,10 @@ func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) bool { // NoErrorf asserts that a function returned no error (i.e. `nil`). // -// actualObj, err := SomeFunction() -// if a.NoErrorf(err, "error message %s", "formatted") { -// assert.Equal(t, expectedObj, actualObj) -// } +// actualObj, err := SomeFunction() +// if a.NoErrorf(err, "error message %s", "formatted") { +// assert.Equal(t, expectedObj, actualObj) +// } func (a *Assertions) NoErrorf(err error, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1024,9 +1108,9 @@ func (a *Assertions) NoFileExistsf(path string, msg string, args ...interface{}) // NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the // specified substring or element. // -// a.NotContains("Hello World", "Earth") -// a.NotContains(["Hello", "World"], "Earth") -// a.NotContains({"Hello": "World"}, "Earth") +// a.NotContains("Hello World", "Earth") +// a.NotContains(["Hello", "World"], "Earth") +// a.NotContains({"Hello": "World"}, "Earth") func (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1037,9 +1121,9 @@ func (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs // NotContainsf asserts that the specified string, list(array, slice...) or map does NOT contain the // specified substring or element. // -// a.NotContainsf("Hello World", "Earth", "error message %s", "formatted") -// a.NotContainsf(["Hello", "World"], "Earth", "error message %s", "formatted") -// a.NotContainsf({"Hello": "World"}, "Earth", "error message %s", "formatted") +// a.NotContainsf("Hello World", "Earth", "error message %s", "formatted") +// a.NotContainsf(["Hello", "World"], "Earth", "error message %s", "formatted") +// a.NotContainsf({"Hello": "World"}, "Earth", "error message %s", "formatted") func (a *Assertions) NotContainsf(s interface{}, contains interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1050,9 +1134,9 @@ func (a *Assertions) NotContainsf(s interface{}, contains interface{}, msg strin // NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either // a slice or a channel with len == 0. // -// if a.NotEmpty(obj) { -// assert.Equal(t, "two", obj[1]) -// } +// if a.NotEmpty(obj) { +// assert.Equal(t, "two", obj[1]) +// } func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1063,9 +1147,9 @@ func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) boo // NotEmptyf asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either // a slice or a channel with len == 0. // -// if a.NotEmptyf(obj, "error message %s", "formatted") { -// assert.Equal(t, "two", obj[1]) -// } +// if a.NotEmptyf(obj, "error message %s", "formatted") { +// assert.Equal(t, "two", obj[1]) +// } func (a *Assertions) NotEmptyf(object interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1075,7 +1159,7 @@ func (a *Assertions) NotEmptyf(object interface{}, msg string, args ...interface // NotEqual asserts that the specified values are NOT equal. // -// a.NotEqual(obj1, obj2) +// a.NotEqual(obj1, obj2) // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). @@ -1088,7 +1172,7 @@ func (a *Assertions) NotEqual(expected interface{}, actual interface{}, msgAndAr // NotEqualValues asserts that two objects are not equal even when converted to the same type // -// a.NotEqualValues(obj1, obj2) +// a.NotEqualValues(obj1, obj2) func (a *Assertions) NotEqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1098,7 +1182,7 @@ func (a *Assertions) NotEqualValues(expected interface{}, actual interface{}, ms // NotEqualValuesf asserts that two objects are not equal even when converted to the same type // -// a.NotEqualValuesf(obj1, obj2, "error message %s", "formatted") +// a.NotEqualValuesf(obj1, obj2, "error message %s", "formatted") func (a *Assertions) NotEqualValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1108,7 +1192,7 @@ func (a *Assertions) NotEqualValuesf(expected interface{}, actual interface{}, m // NotEqualf asserts that the specified values are NOT equal. // -// a.NotEqualf(obj1, obj2, "error message %s", "formatted") +// a.NotEqualf(obj1, obj2, "error message %s", "formatted") // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). @@ -1139,7 +1223,7 @@ func (a *Assertions) NotErrorIsf(err error, target error, msg string, args ...in // NotNil asserts that the specified object is not nil. // -// a.NotNil(err) +// a.NotNil(err) func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1149,7 +1233,7 @@ func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) bool // NotNilf asserts that the specified object is not nil. // -// a.NotNilf(err, "error message %s", "formatted") +// a.NotNilf(err, "error message %s", "formatted") func (a *Assertions) NotNilf(object interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1159,7 +1243,7 @@ func (a *Assertions) NotNilf(object interface{}, msg string, args ...interface{} // NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. // -// a.NotPanics(func(){ RemainCalm() }) +// a.NotPanics(func(){ RemainCalm() }) func (a *Assertions) NotPanics(f PanicTestFunc, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1169,7 +1253,7 @@ func (a *Assertions) NotPanics(f PanicTestFunc, msgAndArgs ...interface{}) bool // NotPanicsf asserts that the code inside the specified PanicTestFunc does NOT panic. // -// a.NotPanicsf(func(){ RemainCalm() }, "error message %s", "formatted") +// a.NotPanicsf(func(){ RemainCalm() }, "error message %s", "formatted") func (a *Assertions) NotPanicsf(f PanicTestFunc, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1179,8 +1263,8 @@ func (a *Assertions) NotPanicsf(f PanicTestFunc, msg string, args ...interface{} // NotRegexp asserts that a specified regexp does not match a string. // -// a.NotRegexp(regexp.MustCompile("starts"), "it's starting") -// a.NotRegexp("^start", "it's not starting") +// a.NotRegexp(regexp.MustCompile("starts"), "it's starting") +// a.NotRegexp("^start", "it's not starting") func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1190,8 +1274,8 @@ func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...in // NotRegexpf asserts that a specified regexp does not match a string. // -// a.NotRegexpf(regexp.MustCompile("starts"), "it's starting", "error message %s", "formatted") -// a.NotRegexpf("^start", "it's not starting", "error message %s", "formatted") +// a.NotRegexpf(regexp.MustCompile("starts"), "it's starting", "error message %s", "formatted") +// a.NotRegexpf("^start", "it's not starting", "error message %s", "formatted") func (a *Assertions) NotRegexpf(rx interface{}, str interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1201,7 +1285,7 @@ func (a *Assertions) NotRegexpf(rx interface{}, str interface{}, msg string, arg // NotSame asserts that two pointers do not reference the same object. // -// a.NotSame(ptr1, ptr2) +// a.NotSame(ptr1, ptr2) // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. @@ -1214,7 +1298,7 @@ func (a *Assertions) NotSame(expected interface{}, actual interface{}, msgAndArg // NotSamef asserts that two pointers do not reference the same object. // -// a.NotSamef(ptr1, ptr2, "error message %s", "formatted") +// a.NotSamef(ptr1, ptr2, "error message %s", "formatted") // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. @@ -1228,7 +1312,7 @@ func (a *Assertions) NotSamef(expected interface{}, actual interface{}, msg stri // NotSubset asserts that the specified list(array, slice...) contains not all // elements given in the specified subset(array, slice...). // -// a.NotSubset([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]") +// a.NotSubset([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]") func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1239,7 +1323,7 @@ func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs // NotSubsetf asserts that the specified list(array, slice...) contains not all // elements given in the specified subset(array, slice...). // -// a.NotSubsetf([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted") +// a.NotSubsetf([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted") func (a *Assertions) NotSubsetf(list interface{}, subset interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1265,7 +1349,7 @@ func (a *Assertions) NotZerof(i interface{}, msg string, args ...interface{}) bo // Panics asserts that the code inside the specified PanicTestFunc panics. // -// a.Panics(func(){ GoCrazy() }) +// a.Panics(func(){ GoCrazy() }) func (a *Assertions) Panics(f PanicTestFunc, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1277,7 +1361,7 @@ func (a *Assertions) Panics(f PanicTestFunc, msgAndArgs ...interface{}) bool { // panics, and that the recovered panic value is an error that satisfies the // EqualError comparison. // -// a.PanicsWithError("crazy error", func(){ GoCrazy() }) +// a.PanicsWithError("crazy error", func(){ GoCrazy() }) func (a *Assertions) PanicsWithError(errString string, f PanicTestFunc, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1289,7 +1373,7 @@ func (a *Assertions) PanicsWithError(errString string, f PanicTestFunc, msgAndAr // panics, and that the recovered panic value is an error that satisfies the // EqualError comparison. // -// a.PanicsWithErrorf("crazy error", func(){ GoCrazy() }, "error message %s", "formatted") +// a.PanicsWithErrorf("crazy error", func(){ GoCrazy() }, "error message %s", "formatted") func (a *Assertions) PanicsWithErrorf(errString string, f PanicTestFunc, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1300,7 +1384,7 @@ func (a *Assertions) PanicsWithErrorf(errString string, f PanicTestFunc, msg str // PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that // the recovered panic value equals the expected panic value. // -// a.PanicsWithValue("crazy error", func(){ GoCrazy() }) +// a.PanicsWithValue("crazy error", func(){ GoCrazy() }) func (a *Assertions) PanicsWithValue(expected interface{}, f PanicTestFunc, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1311,7 +1395,7 @@ func (a *Assertions) PanicsWithValue(expected interface{}, f PanicTestFunc, msgA // PanicsWithValuef asserts that the code inside the specified PanicTestFunc panics, and that // the recovered panic value equals the expected panic value. // -// a.PanicsWithValuef("crazy error", func(){ GoCrazy() }, "error message %s", "formatted") +// a.PanicsWithValuef("crazy error", func(){ GoCrazy() }, "error message %s", "formatted") func (a *Assertions) PanicsWithValuef(expected interface{}, f PanicTestFunc, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1321,7 +1405,7 @@ func (a *Assertions) PanicsWithValuef(expected interface{}, f PanicTestFunc, msg // Panicsf asserts that the code inside the specified PanicTestFunc panics. // -// a.Panicsf(func(){ GoCrazy() }, "error message %s", "formatted") +// a.Panicsf(func(){ GoCrazy() }, "error message %s", "formatted") func (a *Assertions) Panicsf(f PanicTestFunc, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1331,8 +1415,8 @@ func (a *Assertions) Panicsf(f PanicTestFunc, msg string, args ...interface{}) b // Positive asserts that the specified element is positive // -// a.Positive(1) -// a.Positive(1.23) +// a.Positive(1) +// a.Positive(1.23) func (a *Assertions) Positive(e interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1342,8 +1426,8 @@ func (a *Assertions) Positive(e interface{}, msgAndArgs ...interface{}) bool { // Positivef asserts that the specified element is positive // -// a.Positivef(1, "error message %s", "formatted") -// a.Positivef(1.23, "error message %s", "formatted") +// a.Positivef(1, "error message %s", "formatted") +// a.Positivef(1.23, "error message %s", "formatted") func (a *Assertions) Positivef(e interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1353,8 +1437,8 @@ func (a *Assertions) Positivef(e interface{}, msg string, args ...interface{}) b // Regexp asserts that a specified regexp matches a string. // -// a.Regexp(regexp.MustCompile("start"), "it's starting") -// a.Regexp("start...$", "it's not starting") +// a.Regexp(regexp.MustCompile("start"), "it's starting") +// a.Regexp("start...$", "it's not starting") func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1364,8 +1448,8 @@ func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...inter // Regexpf asserts that a specified regexp matches a string. // -// a.Regexpf(regexp.MustCompile("start"), "it's starting", "error message %s", "formatted") -// a.Regexpf("start...$", "it's not starting", "error message %s", "formatted") +// a.Regexpf(regexp.MustCompile("start"), "it's starting", "error message %s", "formatted") +// a.Regexpf("start...$", "it's not starting", "error message %s", "formatted") func (a *Assertions) Regexpf(rx interface{}, str interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1375,7 +1459,7 @@ func (a *Assertions) Regexpf(rx interface{}, str interface{}, msg string, args . // Same asserts that two pointers reference the same object. // -// a.Same(ptr1, ptr2) +// a.Same(ptr1, ptr2) // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. @@ -1388,7 +1472,7 @@ func (a *Assertions) Same(expected interface{}, actual interface{}, msgAndArgs . // Samef asserts that two pointers reference the same object. // -// a.Samef(ptr1, ptr2, "error message %s", "formatted") +// a.Samef(ptr1, ptr2, "error message %s", "formatted") // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. @@ -1402,7 +1486,7 @@ func (a *Assertions) Samef(expected interface{}, actual interface{}, msg string, // Subset asserts that the specified list(array, slice...) contains all // elements given in the specified subset(array, slice...). // -// a.Subset([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]") +// a.Subset([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]") func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1413,7 +1497,7 @@ func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ... // Subsetf asserts that the specified list(array, slice...) contains all // elements given in the specified subset(array, slice...). // -// a.Subsetf([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted") +// a.Subsetf([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted") func (a *Assertions) Subsetf(list interface{}, subset interface{}, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1423,7 +1507,7 @@ func (a *Assertions) Subsetf(list interface{}, subset interface{}, msg string, a // True asserts that the specified value is true. // -// a.True(myBool) +// a.True(myBool) func (a *Assertions) True(value bool, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1433,7 +1517,7 @@ func (a *Assertions) True(value bool, msgAndArgs ...interface{}) bool { // Truef asserts that the specified value is true. // -// a.Truef(myBool, "error message %s", "formatted") +// a.Truef(myBool, "error message %s", "formatted") func (a *Assertions) Truef(value bool, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1443,7 +1527,7 @@ func (a *Assertions) Truef(value bool, msg string, args ...interface{}) bool { // WithinDuration asserts that the two times are within duration delta of each other. // -// a.WithinDuration(time.Now(), time.Now(), 10*time.Second) +// a.WithinDuration(time.Now(), time.Now(), 10*time.Second) func (a *Assertions) WithinDuration(expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1453,7 +1537,7 @@ func (a *Assertions) WithinDuration(expected time.Time, actual time.Time, delta // WithinDurationf asserts that the two times are within duration delta of each other. // -// a.WithinDurationf(time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted") +// a.WithinDurationf(time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted") func (a *Assertions) WithinDurationf(expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1463,7 +1547,7 @@ func (a *Assertions) WithinDurationf(expected time.Time, actual time.Time, delta // WithinRange asserts that a time is within a time range (inclusive). // -// a.WithinRange(time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second)) +// a.WithinRange(time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second)) func (a *Assertions) WithinRange(actual time.Time, start time.Time, end time.Time, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1473,7 +1557,7 @@ func (a *Assertions) WithinRange(actual time.Time, start time.Time, end time.Tim // WithinRangef asserts that a time is within a time range (inclusive). // -// a.WithinRangef(time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), "error message %s", "formatted") +// a.WithinRangef(time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), "error message %s", "formatted") func (a *Assertions) WithinRangef(actual time.Time, start time.Time, end time.Time, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() diff --git a/vendor/github.com/stretchr/testify/assert/assertion_order.go b/vendor/github.com/stretchr/testify/assert/assertion_order.go index 7594487835..00df62a059 100644 --- a/vendor/github.com/stretchr/testify/assert/assertion_order.go +++ b/vendor/github.com/stretchr/testify/assert/assertion_order.go @@ -46,36 +46,36 @@ func isOrdered(t TestingT, object interface{}, allowedComparesResults []CompareT // IsIncreasing asserts that the collection is increasing // -// assert.IsIncreasing(t, []int{1, 2, 3}) -// assert.IsIncreasing(t, []float{1, 2}) -// assert.IsIncreasing(t, []string{"a", "b"}) +// assert.IsIncreasing(t, []int{1, 2, 3}) +// assert.IsIncreasing(t, []float{1, 2}) +// assert.IsIncreasing(t, []string{"a", "b"}) func IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { return isOrdered(t, object, []CompareType{compareLess}, "\"%v\" is not less than \"%v\"", msgAndArgs...) } // IsNonIncreasing asserts that the collection is not increasing // -// assert.IsNonIncreasing(t, []int{2, 1, 1}) -// assert.IsNonIncreasing(t, []float{2, 1}) -// assert.IsNonIncreasing(t, []string{"b", "a"}) +// assert.IsNonIncreasing(t, []int{2, 1, 1}) +// assert.IsNonIncreasing(t, []float{2, 1}) +// assert.IsNonIncreasing(t, []string{"b", "a"}) func IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { return isOrdered(t, object, []CompareType{compareEqual, compareGreater}, "\"%v\" is not greater than or equal to \"%v\"", msgAndArgs...) } // IsDecreasing asserts that the collection is decreasing // -// assert.IsDecreasing(t, []int{2, 1, 0}) -// assert.IsDecreasing(t, []float{2, 1}) -// assert.IsDecreasing(t, []string{"b", "a"}) +// assert.IsDecreasing(t, []int{2, 1, 0}) +// assert.IsDecreasing(t, []float{2, 1}) +// assert.IsDecreasing(t, []string{"b", "a"}) func IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { return isOrdered(t, object, []CompareType{compareGreater}, "\"%v\" is not greater than \"%v\"", msgAndArgs...) } // IsNonDecreasing asserts that the collection is not decreasing // -// assert.IsNonDecreasing(t, []int{1, 1, 2}) -// assert.IsNonDecreasing(t, []float{1, 2}) -// assert.IsNonDecreasing(t, []string{"a", "b"}) +// assert.IsNonDecreasing(t, []int{1, 1, 2}) +// assert.IsNonDecreasing(t, []float{1, 2}) +// assert.IsNonDecreasing(t, []string{"a", "b"}) func IsNonDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { return isOrdered(t, object, []CompareType{compareLess, compareEqual}, "\"%v\" is not less than or equal to \"%v\"", msgAndArgs...) } diff --git a/vendor/github.com/stretchr/testify/assert/assertions.go b/vendor/github.com/stretchr/testify/assert/assertions.go index fa1245b189..a55d1bba92 100644 --- a/vendor/github.com/stretchr/testify/assert/assertions.go +++ b/vendor/github.com/stretchr/testify/assert/assertions.go @@ -8,7 +8,6 @@ import ( "fmt" "math" "os" - "path/filepath" "reflect" "regexp" "runtime" @@ -76,6 +75,77 @@ func ObjectsAreEqual(expected, actual interface{}) bool { return bytes.Equal(exp, act) } +// copyExportedFields iterates downward through nested data structures and creates a copy +// that only contains the exported struct fields. +func copyExportedFields(expected interface{}) interface{} { + if isNil(expected) { + return expected + } + + expectedType := reflect.TypeOf(expected) + expectedKind := expectedType.Kind() + expectedValue := reflect.ValueOf(expected) + + switch expectedKind { + case reflect.Struct: + result := reflect.New(expectedType).Elem() + for i := 0; i < expectedType.NumField(); i++ { + field := expectedType.Field(i) + isExported := field.IsExported() + if isExported { + fieldValue := expectedValue.Field(i) + if isNil(fieldValue) || isNil(fieldValue.Interface()) { + continue + } + newValue := copyExportedFields(fieldValue.Interface()) + result.Field(i).Set(reflect.ValueOf(newValue)) + } + } + return result.Interface() + + case reflect.Ptr: + result := reflect.New(expectedType.Elem()) + unexportedRemoved := copyExportedFields(expectedValue.Elem().Interface()) + result.Elem().Set(reflect.ValueOf(unexportedRemoved)) + return result.Interface() + + case reflect.Array, reflect.Slice: + result := reflect.MakeSlice(expectedType, expectedValue.Len(), expectedValue.Len()) + for i := 0; i < expectedValue.Len(); i++ { + index := expectedValue.Index(i) + if isNil(index) { + continue + } + unexportedRemoved := copyExportedFields(index.Interface()) + result.Index(i).Set(reflect.ValueOf(unexportedRemoved)) + } + return result.Interface() + + case reflect.Map: + result := reflect.MakeMap(expectedType) + for _, k := range expectedValue.MapKeys() { + index := expectedValue.MapIndex(k) + unexportedRemoved := copyExportedFields(index.Interface()) + result.SetMapIndex(k, reflect.ValueOf(unexportedRemoved)) + } + return result.Interface() + + default: + return expected + } +} + +// ObjectsExportedFieldsAreEqual determines if the exported (public) fields of two objects are +// considered equal. This comparison of only exported fields is applied recursively to nested data +// structures. +// +// This function does no assertion of any kind. +func ObjectsExportedFieldsAreEqual(expected, actual interface{}) bool { + expectedCleaned := copyExportedFields(expected) + actualCleaned := copyExportedFields(actual) + return ObjectsAreEqualValues(expectedCleaned, actualCleaned) +} + // ObjectsAreEqualValues gets whether two objects are equal, or if their // values are equal. func ObjectsAreEqualValues(expected, actual interface{}) bool { @@ -141,12 +211,11 @@ func CallerInfo() []string { } parts := strings.Split(file, "/") - file = parts[len(parts)-1] if len(parts) > 1 { + filename := parts[len(parts)-1] dir := parts[len(parts)-2] - if (dir != "assert" && dir != "mock" && dir != "require") || file == "mock_test.go" { - path, _ := filepath.Abs(file) - callers = append(callers, fmt.Sprintf("%s:%d", path, line)) + if (dir != "assert" && dir != "mock" && dir != "require") || filename == "mock_test.go" { + callers = append(callers, fmt.Sprintf("%s:%d", file, line)) } } @@ -273,7 +342,7 @@ type labeledContent struct { // labeledOutput returns a string consisting of the provided labeledContent. Each labeled output is appended in the following manner: // -// \t{{label}}:{{align_spaces}}\t{{content}}\n +// \t{{label}}:{{align_spaces}}\t{{content}}\n // // The initial carriage return is required to undo/erase any padding added by testing.T.Errorf. The "\t{{label}}:" is for the label. // If a label is shorter than the longest label provided, padding spaces are added to make all the labels match in length. Once this @@ -296,7 +365,7 @@ func labeledOutput(content ...labeledContent) string { // Implements asserts that an object is implemented by the specified interface. // -// assert.Implements(t, (*MyInterface)(nil), new(MyObject)) +// assert.Implements(t, (*MyInterface)(nil), new(MyObject)) func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -328,7 +397,7 @@ func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs // Equal asserts that two objects are equal. // -// assert.Equal(t, 123, 123) +// assert.Equal(t, 123, 123) // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). Function equality @@ -369,7 +438,7 @@ func validateEqualArgs(expected, actual interface{}) error { // Same asserts that two pointers reference the same object. // -// assert.Same(t, ptr1, ptr2) +// assert.Same(t, ptr1, ptr2) // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. @@ -389,7 +458,7 @@ func Same(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) b // NotSame asserts that two pointers do not reference the same object. // -// assert.NotSame(t, ptr1, ptr2) +// assert.NotSame(t, ptr1, ptr2) // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. @@ -457,7 +526,7 @@ func truncatingFormat(data interface{}) string { // EqualValues asserts that two objects are equal or convertable to the same types // and equal. // -// assert.EqualValues(t, uint32(123), int32(123)) +// assert.EqualValues(t, uint32(123), int32(123)) func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -475,9 +544,53 @@ func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interfa } +// EqualExportedValues asserts that the types of two objects are equal and their public +// fields are also equal. This is useful for comparing structs that have private fields +// that could potentially differ. +// +// type S struct { +// Exported int +// notExported int +// } +// assert.EqualExportedValues(t, S{1, 2}, S{1, 3}) => true +// assert.EqualExportedValues(t, S{1, 2}, S{2, 3}) => false +func EqualExportedValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + aType := reflect.TypeOf(expected) + bType := reflect.TypeOf(actual) + + if aType != bType { + return Fail(t, fmt.Sprintf("Types expected to match exactly\n\t%v != %v", aType, bType), msgAndArgs...) + } + + if aType.Kind() != reflect.Struct { + return Fail(t, fmt.Sprintf("Types expected to both be struct \n\t%v != %v", aType.Kind(), reflect.Struct), msgAndArgs...) + } + + if bType.Kind() != reflect.Struct { + return Fail(t, fmt.Sprintf("Types expected to both be struct \n\t%v != %v", bType.Kind(), reflect.Struct), msgAndArgs...) + } + + expected = copyExportedFields(expected) + actual = copyExportedFields(actual) + + if !ObjectsAreEqualValues(expected, actual) { + diff := diff(expected, actual) + expected, actual = formatUnequalValues(expected, actual) + return Fail(t, fmt.Sprintf("Not equal (comparing only exported fields): \n"+ + "expected: %s\n"+ + "actual : %s%s", expected, actual, diff), msgAndArgs...) + } + + return true +} + // Exactly asserts that two objects are equal in value and type. // -// assert.Exactly(t, int32(123), int64(123)) +// assert.Exactly(t, int32(123), int64(123)) func Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -496,7 +609,7 @@ func Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{} // NotNil asserts that the specified object is not nil. // -// assert.NotNil(t, err) +// assert.NotNil(t, err) func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { if !isNil(object) { return true @@ -530,7 +643,7 @@ func isNil(object interface{}) bool { []reflect.Kind{ reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, - reflect.Ptr, reflect.Slice}, + reflect.Ptr, reflect.Slice, reflect.UnsafePointer}, kind) if isNilableKind && value.IsNil() { @@ -542,7 +655,7 @@ func isNil(object interface{}) bool { // Nil asserts that the specified object is nil. // -// assert.Nil(t, err) +// assert.Nil(t, err) func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { if isNil(object) { return true @@ -585,7 +698,7 @@ func isEmpty(object interface{}) bool { // Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either // a slice or a channel with len == 0. // -// assert.Empty(t, obj) +// assert.Empty(t, obj) func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { pass := isEmpty(object) if !pass { @@ -602,9 +715,9 @@ func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { // NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either // a slice or a channel with len == 0. // -// if assert.NotEmpty(t, obj) { -// assert.Equal(t, "two", obj[1]) -// } +// if assert.NotEmpty(t, obj) { +// assert.Equal(t, "two", obj[1]) +// } func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { pass := !isEmpty(object) if !pass { @@ -633,7 +746,7 @@ func getLen(x interface{}) (ok bool, length int) { // Len asserts that the specified object has specific length. // Len also fails if the object has a type that len() not accept. // -// assert.Len(t, mySlice, 3) +// assert.Len(t, mySlice, 3) func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -651,7 +764,7 @@ func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) // True asserts that the specified value is true. // -// assert.True(t, myBool) +// assert.True(t, myBool) func True(t TestingT, value bool, msgAndArgs ...interface{}) bool { if !value { if h, ok := t.(tHelper); ok { @@ -666,7 +779,7 @@ func True(t TestingT, value bool, msgAndArgs ...interface{}) bool { // False asserts that the specified value is false. // -// assert.False(t, myBool) +// assert.False(t, myBool) func False(t TestingT, value bool, msgAndArgs ...interface{}) bool { if value { if h, ok := t.(tHelper); ok { @@ -681,7 +794,7 @@ func False(t TestingT, value bool, msgAndArgs ...interface{}) bool { // NotEqual asserts that the specified values are NOT equal. // -// assert.NotEqual(t, obj1, obj2) +// assert.NotEqual(t, obj1, obj2) // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). @@ -704,7 +817,7 @@ func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{ // NotEqualValues asserts that two objects are not equal even when converted to the same type // -// assert.NotEqualValues(t, obj1, obj2) +// assert.NotEqualValues(t, obj1, obj2) func NotEqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -763,9 +876,9 @@ func containsElement(list interface{}, element interface{}) (ok, found bool) { // Contains asserts that the specified string, list(array, slice...) or map contains the // specified substring or element. // -// assert.Contains(t, "Hello World", "World") -// assert.Contains(t, ["Hello", "World"], "World") -// assert.Contains(t, {"Hello": "World"}, "Hello") +// assert.Contains(t, "Hello World", "World") +// assert.Contains(t, ["Hello", "World"], "World") +// assert.Contains(t, {"Hello": "World"}, "Hello") func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -786,9 +899,9 @@ func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bo // NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the // specified substring or element. // -// assert.NotContains(t, "Hello World", "Earth") -// assert.NotContains(t, ["Hello", "World"], "Earth") -// assert.NotContains(t, {"Hello": "World"}, "Earth") +// assert.NotContains(t, "Hello World", "Earth") +// assert.NotContains(t, ["Hello", "World"], "Earth") +// assert.NotContains(t, {"Hello": "World"}, "Earth") func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -796,10 +909,10 @@ func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) ok, found := containsElement(s, contains) if !ok { - return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", s), msgAndArgs...) + return Fail(t, fmt.Sprintf("%#v could not be applied builtin len()", s), msgAndArgs...) } if found { - return Fail(t, fmt.Sprintf("\"%s\" should not contain \"%s\"", s, contains), msgAndArgs...) + return Fail(t, fmt.Sprintf("%#v should not contain %#v", s, contains), msgAndArgs...) } return true @@ -809,7 +922,7 @@ func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) // Subset asserts that the specified list(array, slice...) contains all // elements given in the specified subset(array, slice...). // -// assert.Subset(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]") +// assert.Subset(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]") func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) { if h, ok := t.(tHelper); ok { h.Helper() @@ -818,49 +931,44 @@ func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok return true // we consider nil to be equal to the nil set } - defer func() { - if e := recover(); e != nil { - ok = false - } - }() - listKind := reflect.TypeOf(list).Kind() - subsetKind := reflect.TypeOf(subset).Kind() - if listKind != reflect.Array && listKind != reflect.Slice && listKind != reflect.Map { return Fail(t, fmt.Sprintf("%q has an unsupported type %s", list, listKind), msgAndArgs...) } + subsetKind := reflect.TypeOf(subset).Kind() if subsetKind != reflect.Array && subsetKind != reflect.Slice && listKind != reflect.Map { return Fail(t, fmt.Sprintf("%q has an unsupported type %s", subset, subsetKind), msgAndArgs...) } - subsetValue := reflect.ValueOf(subset) if subsetKind == reflect.Map && listKind == reflect.Map { - listValue := reflect.ValueOf(list) - subsetKeys := subsetValue.MapKeys() + subsetMap := reflect.ValueOf(subset) + actualMap := reflect.ValueOf(list) - for i := 0; i < len(subsetKeys); i++ { - subsetKey := subsetKeys[i] - subsetElement := subsetValue.MapIndex(subsetKey).Interface() - listElement := listValue.MapIndex(subsetKey).Interface() + for _, k := range subsetMap.MapKeys() { + ev := subsetMap.MapIndex(k) + av := actualMap.MapIndex(k) - if !ObjectsAreEqual(subsetElement, listElement) { - return Fail(t, fmt.Sprintf("\"%s\" does not contain \"%s\"", list, subsetElement), msgAndArgs...) + if !av.IsValid() { + return Fail(t, fmt.Sprintf("%#v does not contain %#v", list, subset), msgAndArgs...) + } + if !ObjectsAreEqual(ev.Interface(), av.Interface()) { + return Fail(t, fmt.Sprintf("%#v does not contain %#v", list, subset), msgAndArgs...) } } return true } - for i := 0; i < subsetValue.Len(); i++ { - element := subsetValue.Index(i).Interface() + subsetList := reflect.ValueOf(subset) + for i := 0; i < subsetList.Len(); i++ { + element := subsetList.Index(i).Interface() ok, found := containsElement(list, element) if !ok { - return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", list), msgAndArgs...) + return Fail(t, fmt.Sprintf("%#v could not be applied builtin len()", list), msgAndArgs...) } if !found { - return Fail(t, fmt.Sprintf("\"%s\" does not contain \"%s\"", list, element), msgAndArgs...) + return Fail(t, fmt.Sprintf("%#v does not contain %#v", list, element), msgAndArgs...) } } @@ -870,7 +978,7 @@ func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok // NotSubset asserts that the specified list(array, slice...) contains not all // elements given in the specified subset(array, slice...). // -// assert.NotSubset(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]") +// assert.NotSubset(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]") func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) { if h, ok := t.(tHelper); ok { h.Helper() @@ -879,34 +987,28 @@ func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) return Fail(t, "nil is the empty set which is a subset of every set", msgAndArgs...) } - defer func() { - if e := recover(); e != nil { - ok = false - } - }() - listKind := reflect.TypeOf(list).Kind() - subsetKind := reflect.TypeOf(subset).Kind() - if listKind != reflect.Array && listKind != reflect.Slice && listKind != reflect.Map { return Fail(t, fmt.Sprintf("%q has an unsupported type %s", list, listKind), msgAndArgs...) } + subsetKind := reflect.TypeOf(subset).Kind() if subsetKind != reflect.Array && subsetKind != reflect.Slice && listKind != reflect.Map { return Fail(t, fmt.Sprintf("%q has an unsupported type %s", subset, subsetKind), msgAndArgs...) } - subsetValue := reflect.ValueOf(subset) if subsetKind == reflect.Map && listKind == reflect.Map { - listValue := reflect.ValueOf(list) - subsetKeys := subsetValue.MapKeys() + subsetMap := reflect.ValueOf(subset) + actualMap := reflect.ValueOf(list) - for i := 0; i < len(subsetKeys); i++ { - subsetKey := subsetKeys[i] - subsetElement := subsetValue.MapIndex(subsetKey).Interface() - listElement := listValue.MapIndex(subsetKey).Interface() + for _, k := range subsetMap.MapKeys() { + ev := subsetMap.MapIndex(k) + av := actualMap.MapIndex(k) - if !ObjectsAreEqual(subsetElement, listElement) { + if !av.IsValid() { + return true + } + if !ObjectsAreEqual(ev.Interface(), av.Interface()) { return true } } @@ -914,8 +1016,9 @@ func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) return Fail(t, fmt.Sprintf("%q is a subset of %q", subset, list), msgAndArgs...) } - for i := 0; i < subsetValue.Len(); i++ { - element := subsetValue.Index(i).Interface() + subsetList := reflect.ValueOf(subset) + for i := 0; i < subsetList.Len(); i++ { + element := subsetList.Index(i).Interface() ok, found := containsElement(list, element) if !ok { return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", list), msgAndArgs...) @@ -1060,7 +1163,7 @@ func didPanic(f PanicTestFunc) (didPanic bool, message interface{}, stack string // Panics asserts that the code inside the specified PanicTestFunc panics. // -// assert.Panics(t, func(){ GoCrazy() }) +// assert.Panics(t, func(){ GoCrazy() }) func Panics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -1076,7 +1179,7 @@ func Panics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool { // PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that // the recovered panic value equals the expected panic value. // -// assert.PanicsWithValue(t, "crazy error", func(){ GoCrazy() }) +// assert.PanicsWithValue(t, "crazy error", func(){ GoCrazy() }) func PanicsWithValue(t TestingT, expected interface{}, f PanicTestFunc, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -1097,7 +1200,7 @@ func PanicsWithValue(t TestingT, expected interface{}, f PanicTestFunc, msgAndAr // panics, and that the recovered panic value is an error that satisfies the // EqualError comparison. // -// assert.PanicsWithError(t, "crazy error", func(){ GoCrazy() }) +// assert.PanicsWithError(t, "crazy error", func(){ GoCrazy() }) func PanicsWithError(t TestingT, errString string, f PanicTestFunc, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -1117,7 +1220,7 @@ func PanicsWithError(t TestingT, errString string, f PanicTestFunc, msgAndArgs . // NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. // -// assert.NotPanics(t, func(){ RemainCalm() }) +// assert.NotPanics(t, func(){ RemainCalm() }) func NotPanics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -1132,7 +1235,7 @@ func NotPanics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool { // WithinDuration asserts that the two times are within duration delta of each other. // -// assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second) +// assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second) func WithinDuration(t TestingT, expected, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -1148,7 +1251,7 @@ func WithinDuration(t TestingT, expected, actual time.Time, delta time.Duration, // WithinRange asserts that a time is within a time range (inclusive). // -// assert.WithinRange(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second)) +// assert.WithinRange(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second)) func WithinRange(t TestingT, actual, start, end time.Time, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -1207,7 +1310,7 @@ func toFloat(x interface{}) (float64, bool) { // InDelta asserts that the two numerals are within delta of each other. // -// assert.InDelta(t, math.Pi, 22/7.0, 0.01) +// assert.InDelta(t, math.Pi, 22/7.0, 0.01) func InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -1380,10 +1483,10 @@ func InEpsilonSlice(t TestingT, expected, actual interface{}, epsilon float64, m // NoError asserts that a function returned no error (i.e. `nil`). // -// actualObj, err := SomeFunction() -// if assert.NoError(t, err) { -// assert.Equal(t, expectedObj, actualObj) -// } +// actualObj, err := SomeFunction() +// if assert.NoError(t, err) { +// assert.Equal(t, expectedObj, actualObj) +// } func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool { if err != nil { if h, ok := t.(tHelper); ok { @@ -1397,10 +1500,10 @@ func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool { // Error asserts that a function returned an error (i.e. not `nil`). // -// actualObj, err := SomeFunction() -// if assert.Error(t, err) { -// assert.Equal(t, expectedError, err) -// } +// actualObj, err := SomeFunction() +// if assert.Error(t, err) { +// assert.Equal(t, expectedError, err) +// } func Error(t TestingT, err error, msgAndArgs ...interface{}) bool { if err == nil { if h, ok := t.(tHelper); ok { @@ -1415,8 +1518,8 @@ func Error(t TestingT, err error, msgAndArgs ...interface{}) bool { // EqualError asserts that a function returned an error (i.e. not `nil`) // and that it is equal to the provided error. // -// actualObj, err := SomeFunction() -// assert.EqualError(t, err, expectedErrorString) +// actualObj, err := SomeFunction() +// assert.EqualError(t, err, expectedErrorString) func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -1438,8 +1541,8 @@ func EqualError(t TestingT, theError error, errString string, msgAndArgs ...inte // ErrorContains asserts that a function returned an error (i.e. not `nil`) // and that the error contains the specified substring. // -// actualObj, err := SomeFunction() -// assert.ErrorContains(t, err, expectedErrorSubString) +// actualObj, err := SomeFunction() +// assert.ErrorContains(t, err, expectedErrorSubString) func ErrorContains(t TestingT, theError error, contains string, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -1472,8 +1575,8 @@ func matchRegexp(rx interface{}, str interface{}) bool { // Regexp asserts that a specified regexp matches a string. // -// assert.Regexp(t, regexp.MustCompile("start"), "it's starting") -// assert.Regexp(t, "start...$", "it's not starting") +// assert.Regexp(t, regexp.MustCompile("start"), "it's starting") +// assert.Regexp(t, "start...$", "it's not starting") func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -1490,8 +1593,8 @@ func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface // NotRegexp asserts that a specified regexp does not match a string. // -// assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting") -// assert.NotRegexp(t, "^start", "it's not starting") +// assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting") +// assert.NotRegexp(t, "^start", "it's not starting") func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -1603,7 +1706,7 @@ func NoDirExists(t TestingT, path string, msgAndArgs ...interface{}) bool { // JSONEq asserts that two JSON strings are equivalent. // -// assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) +// assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -1726,7 +1829,7 @@ type tHelper interface { // Eventually asserts that given condition will be met in waitFor time, // periodically checking target function each tick. // -// assert.Eventually(t, func() bool { return true; }, time.Second, 10*time.Millisecond) +// assert.Eventually(t, func() bool { return true; }, time.Second, 10*time.Millisecond) func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -1756,10 +1859,93 @@ func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick t } } +// CollectT implements the TestingT interface and collects all errors. +type CollectT struct { + errors []error +} + +// Errorf collects the error. +func (c *CollectT) Errorf(format string, args ...interface{}) { + c.errors = append(c.errors, fmt.Errorf(format, args...)) +} + +// FailNow panics. +func (c *CollectT) FailNow() { + panic("Assertion failed") +} + +// Reset clears the collected errors. +func (c *CollectT) Reset() { + c.errors = nil +} + +// Copy copies the collected errors to the supplied t. +func (c *CollectT) Copy(t TestingT) { + if tt, ok := t.(tHelper); ok { + tt.Helper() + } + for _, err := range c.errors { + t.Errorf("%v", err) + } +} + +// EventuallyWithT asserts that given condition will be met in waitFor time, +// periodically checking target function each tick. In contrast to Eventually, +// it supplies a CollectT to the condition function, so that the condition +// function can use the CollectT to call other assertions. +// The condition is considered "met" if no errors are raised in a tick. +// The supplied CollectT collects all errors from one tick (if there are any). +// If the condition is not met before waitFor, the collected errors of +// the last tick are copied to t. +// +// externalValue := false +// go func() { +// time.Sleep(8*time.Second) +// externalValue = true +// }() +// assert.EventuallyWithT(t, func(c *assert.CollectT) { +// // add assertions as needed; any assertion failure will fail the current tick +// assert.True(c, externalValue, "expected 'externalValue' to be true") +// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") +func EventuallyWithT(t TestingT, condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + collect := new(CollectT) + ch := make(chan bool, 1) + + timer := time.NewTimer(waitFor) + defer timer.Stop() + + ticker := time.NewTicker(tick) + defer ticker.Stop() + + for tick := ticker.C; ; { + select { + case <-timer.C: + collect.Copy(t) + return Fail(t, "Condition never satisfied", msgAndArgs...) + case <-tick: + tick = nil + collect.Reset() + go func() { + condition(collect) + ch <- len(collect.errors) == 0 + }() + case v := <-ch: + if v { + return true + } + tick = ticker.C + } + } +} + // Never asserts that the given condition doesn't satisfy in waitFor time, // periodically checking the target function each tick. // -// assert.Never(t, func() bool { return false; }, time.Second, 10*time.Millisecond) +// assert.Never(t, func() bool { return false; }, time.Second, 10*time.Millisecond) func Never(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() diff --git a/vendor/github.com/stretchr/testify/assert/doc.go b/vendor/github.com/stretchr/testify/assert/doc.go index c9dccc4d6c..4953981d38 100644 --- a/vendor/github.com/stretchr/testify/assert/doc.go +++ b/vendor/github.com/stretchr/testify/assert/doc.go @@ -1,39 +1,40 @@ // Package assert provides a set of comprehensive testing tools for use with the normal Go testing system. // -// Example Usage +// # Example Usage // // The following is a complete example using assert in a standard test function: -// import ( -// "testing" -// "github.com/stretchr/testify/assert" -// ) // -// func TestSomething(t *testing.T) { +// import ( +// "testing" +// "github.com/stretchr/testify/assert" +// ) // -// var a string = "Hello" -// var b string = "Hello" +// func TestSomething(t *testing.T) { // -// assert.Equal(t, a, b, "The two words should be the same.") +// var a string = "Hello" +// var b string = "Hello" // -// } +// assert.Equal(t, a, b, "The two words should be the same.") +// +// } // // if you assert many times, use the format below: // -// import ( -// "testing" -// "github.com/stretchr/testify/assert" -// ) +// import ( +// "testing" +// "github.com/stretchr/testify/assert" +// ) // -// func TestSomething(t *testing.T) { -// assert := assert.New(t) +// func TestSomething(t *testing.T) { +// assert := assert.New(t) // -// var a string = "Hello" -// var b string = "Hello" +// var a string = "Hello" +// var b string = "Hello" // -// assert.Equal(a, b, "The two words should be the same.") -// } +// assert.Equal(a, b, "The two words should be the same.") +// } // -// Assertions +// # Assertions // // Assertions allow you to easily write test code, and are global funcs in the `assert` package. // All assertion functions take, as the first argument, the `*testing.T` object provided by the diff --git a/vendor/github.com/stretchr/testify/assert/http_assertions.go b/vendor/github.com/stretchr/testify/assert/http_assertions.go index 4ed341dd28..d8038c28a7 100644 --- a/vendor/github.com/stretchr/testify/assert/http_assertions.go +++ b/vendor/github.com/stretchr/testify/assert/http_assertions.go @@ -23,7 +23,7 @@ func httpCode(handler http.HandlerFunc, method, url string, values url.Values) ( // HTTPSuccess asserts that a specified handler returns a success status code. // -// assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil) +// assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil) // // Returns whether the assertion was successful (true) or not (false). func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool { @@ -45,7 +45,7 @@ func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, value // HTTPRedirect asserts that a specified handler returns a redirect status code. // -// assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool { @@ -67,7 +67,7 @@ func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, valu // HTTPError asserts that a specified handler returns an error status code. // -// assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). func HTTPError(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool { @@ -89,7 +89,7 @@ func HTTPError(t TestingT, handler http.HandlerFunc, method, url string, values // HTTPStatusCode asserts that a specified handler returns a specified status code. // -// assert.HTTPStatusCode(t, myHandler, "GET", "/notImplemented", nil, 501) +// assert.HTTPStatusCode(t, myHandler, "GET", "/notImplemented", nil, 501) // // Returns whether the assertion was successful (true) or not (false). func HTTPStatusCode(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, statuscode int, msgAndArgs ...interface{}) bool { @@ -124,7 +124,7 @@ func HTTPBody(handler http.HandlerFunc, method, url string, values url.Values) s // HTTPBodyContains asserts that a specified handler returns a // body that contains a string. // -// assert.HTTPBodyContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") +// assert.HTTPBodyContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") // // Returns whether the assertion was successful (true) or not (false). func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool { @@ -144,7 +144,7 @@ func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string, // HTTPBodyNotContains asserts that a specified handler returns a // body that does not contain a string. // -// assert.HTTPBodyNotContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") +// assert.HTTPBodyNotContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") // // Returns whether the assertion was successful (true) or not (false). func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool { diff --git a/vendor/github.com/stretchr/testify/mock/doc.go b/vendor/github.com/stretchr/testify/mock/doc.go index 7324128ef1..d6b3c844cc 100644 --- a/vendor/github.com/stretchr/testify/mock/doc.go +++ b/vendor/github.com/stretchr/testify/mock/doc.go @@ -1,17 +1,17 @@ // Package mock provides a system by which it is possible to mock your objects // and verify calls are happening as expected. // -// Example Usage +// # Example Usage // // The mock package provides an object, Mock, that tracks activity on another object. It is usually // embedded into a test object as shown below: // -// type MyTestObject struct { -// // add a Mock object instance -// mock.Mock +// type MyTestObject struct { +// // add a Mock object instance +// mock.Mock // -// // other fields go here as normal -// } +// // other fields go here as normal +// } // // When implementing the methods of an interface, you wire your functions up // to call the Mock.Called(args...) method, and return the appropriate values. @@ -19,25 +19,25 @@ // For example, to mock a method that saves the name and age of a person and returns // the year of their birth or an error, you might write this: // -// func (o *MyTestObject) SavePersonDetails(firstname, lastname string, age int) (int, error) { -// args := o.Called(firstname, lastname, age) -// return args.Int(0), args.Error(1) -// } +// func (o *MyTestObject) SavePersonDetails(firstname, lastname string, age int) (int, error) { +// args := o.Called(firstname, lastname, age) +// return args.Int(0), args.Error(1) +// } // // The Int, Error and Bool methods are examples of strongly typed getters that take the argument // index position. Given this argument list: // -// (12, true, "Something") +// (12, true, "Something") // // You could read them out strongly typed like this: // -// args.Int(0) -// args.Bool(1) -// args.String(2) +// args.Int(0) +// args.Bool(1) +// args.String(2) // // For objects of your own type, use the generic Arguments.Get(index) method and make a type assertion: // -// return args.Get(0).(*MyObject), args.Get(1).(*AnotherObjectOfMine) +// return args.Get(0).(*MyObject), args.Get(1).(*AnotherObjectOfMine) // // This may cause a panic if the object you are getting is nil (the type assertion will fail), in those // cases you should check for nil first. diff --git a/vendor/github.com/stretchr/testify/mock/mock.go b/vendor/github.com/stretchr/testify/mock/mock.go index f0af8246cf..f4b42e44ff 100644 --- a/vendor/github.com/stretchr/testify/mock/mock.go +++ b/vendor/github.com/stretchr/testify/mock/mock.go @@ -3,6 +3,7 @@ package mock import ( "errors" "fmt" + "path" "reflect" "regexp" "runtime" @@ -13,6 +14,7 @@ import ( "github.com/davecgh/go-spew/spew" "github.com/pmezard/go-difflib/difflib" "github.com/stretchr/objx" + "github.com/stretchr/testify/assert" ) @@ -99,7 +101,7 @@ func (c *Call) unlock() { // Return specifies the return arguments for the expectation. // -// Mock.On("DoSomething").Return(errors.New("failed")) +// Mock.On("DoSomething").Return(errors.New("failed")) func (c *Call) Return(returnArguments ...interface{}) *Call { c.lock() defer c.unlock() @@ -111,7 +113,7 @@ func (c *Call) Return(returnArguments ...interface{}) *Call { // Panic specifies if the functon call should fail and the panic message // -// Mock.On("DoSomething").Panic("test panic") +// Mock.On("DoSomething").Panic("test panic") func (c *Call) Panic(msg string) *Call { c.lock() defer c.unlock() @@ -123,14 +125,14 @@ func (c *Call) Panic(msg string) *Call { // Once indicates that that the mock should only return the value once. // -// Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2).Once() +// Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2).Once() func (c *Call) Once() *Call { return c.Times(1) } // Twice indicates that that the mock should only return the value twice. // -// Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2).Twice() +// Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2).Twice() func (c *Call) Twice() *Call { return c.Times(2) } @@ -138,7 +140,7 @@ func (c *Call) Twice() *Call { // Times indicates that that the mock should only return the indicated number // of times. // -// Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2).Times(5) +// Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2).Times(5) func (c *Call) Times(i int) *Call { c.lock() defer c.unlock() @@ -149,7 +151,7 @@ func (c *Call) Times(i int) *Call { // WaitUntil sets the channel that will block the mock's return until its closed // or a message is received. // -// Mock.On("MyMethod", arg1, arg2).WaitUntil(time.After(time.Second)) +// Mock.On("MyMethod", arg1, arg2).WaitUntil(time.After(time.Second)) func (c *Call) WaitUntil(w <-chan time.Time) *Call { c.lock() defer c.unlock() @@ -159,7 +161,7 @@ func (c *Call) WaitUntil(w <-chan time.Time) *Call { // After sets how long to block until the call returns // -// Mock.On("MyMethod", arg1, arg2).After(time.Second) +// Mock.On("MyMethod", arg1, arg2).After(time.Second) func (c *Call) After(d time.Duration) *Call { c.lock() defer c.unlock() @@ -171,10 +173,10 @@ func (c *Call) After(d time.Duration) *Call { // mocking a method (such as an unmarshaler) that takes a pointer to a struct and // sets properties in such struct // -// Mock.On("Unmarshal", AnythingOfType("*map[string]interface{}")).Return().Run(func(args Arguments) { -// arg := args.Get(0).(*map[string]interface{}) -// arg["foo"] = "bar" -// }) +// Mock.On("Unmarshal", AnythingOfType("*map[string]interface{}")).Return().Run(func(args Arguments) { +// arg := args.Get(0).(*map[string]interface{}) +// arg["foo"] = "bar" +// }) func (c *Call) Run(fn func(args Arguments)) *Call { c.lock() defer c.unlock() @@ -194,16 +196,18 @@ func (c *Call) Maybe() *Call { // On chains a new expectation description onto the mocked interface. This // allows syntax like. // -// Mock. -// On("MyMethod", 1).Return(nil). -// On("MyOtherMethod", 'a', 'b', 'c').Return(errors.New("Some Error")) +// Mock. +// On("MyMethod", 1).Return(nil). +// On("MyOtherMethod", 'a', 'b', 'c').Return(errors.New("Some Error")) +// //go:noinline func (c *Call) On(methodName string, arguments ...interface{}) *Call { return c.Parent.On(methodName, arguments...) } // Unset removes a mock handler from being called. -// test.On("func", mock.Anything).Unset() +// +// test.On("func", mock.Anything).Unset() func (c *Call) Unset() *Call { var unlockOnce sync.Once @@ -218,16 +222,22 @@ func (c *Call) Unset() *Call { foundMatchingCall := false - for i, call := range c.Parent.ExpectedCalls { + // in-place filter slice for calls to be removed - iterate from 0'th to last skipping unnecessary ones + var index int // write index + for _, call := range c.Parent.ExpectedCalls { if call.Method == c.Method { _, diffCount := call.Arguments.Diff(c.Arguments) if diffCount == 0 { foundMatchingCall = true - // Remove from ExpectedCalls - c.Parent.ExpectedCalls = append(c.Parent.ExpectedCalls[:i], c.Parent.ExpectedCalls[i+1:]...) + // Remove from ExpectedCalls - just skip it + continue } } + c.Parent.ExpectedCalls[index] = call + index++ } + // trim slice up to last copied index + c.Parent.ExpectedCalls = c.Parent.ExpectedCalls[:index] if !foundMatchingCall { unlockOnce.Do(c.unlock) @@ -243,9 +253,9 @@ func (c *Call) Unset() *Call { // calls have been called as expected. The referenced calls may be from the // same mock instance and/or other mock instances. // -// Mock.On("Do").Return(nil).Notbefore( -// Mock.On("Init").Return(nil) -// ) +// Mock.On("Do").Return(nil).Notbefore( +// Mock.On("Init").Return(nil) +// ) func (c *Call) NotBefore(calls ...*Call) *Call { c.lock() defer c.unlock() @@ -328,7 +338,7 @@ func (m *Mock) fail(format string, args ...interface{}) { // On starts a description of an expectation of the specified method // being called. // -// Mock.On("MyMethod", arg1, arg2) +// Mock.On("MyMethod", arg1, arg2) func (m *Mock) On(methodName string, arguments ...interface{}) *Call { for _, arg := range arguments { if v := reflect.ValueOf(arg); v.Kind() == reflect.Func { @@ -418,6 +428,10 @@ func callString(method string, arguments Arguments, includeArgumentValues bool) if includeArgumentValues { var argVals []string for argIndex, arg := range arguments { + if _, ok := arg.(*FunctionalOptionsArgument); ok { + argVals = append(argVals, fmt.Sprintf("%d: %s", argIndex, arg)) + continue + } argVals = append(argVals, fmt.Sprintf("%d: %#v", argIndex, arg)) } argValsString = fmt.Sprintf("\n\t\t%s", strings.Join(argVals, "\n\t\t")) @@ -752,6 +766,7 @@ type AnythingOfTypeArgument string // name of the type to check for. Used in Diff and Assert. // // For example: +// // Assert(t, AnythingOfType("string"), AnythingOfType("int")) func AnythingOfType(t string) AnythingOfTypeArgument { return AnythingOfTypeArgument(t) @@ -774,6 +789,34 @@ func IsType(t interface{}) *IsTypeArgument { return &IsTypeArgument{t: t} } +// FunctionalOptionsArgument is a struct that contains the type and value of an functional option argument +// for use when type checking. +type FunctionalOptionsArgument struct { + value interface{} +} + +// String returns the string representation of FunctionalOptionsArgument +func (f *FunctionalOptionsArgument) String() string { + var name string + tValue := reflect.ValueOf(f.value) + if tValue.Len() > 0 { + name = "[]" + reflect.TypeOf(tValue.Index(0).Interface()).String() + } + + return strings.Replace(fmt.Sprintf("%#v", f.value), "[]interface {}", name, 1) +} + +// FunctionalOptions returns an FunctionalOptionsArgument object containing the functional option type +// and the values to check of +// +// For example: +// Assert(t, FunctionalOptions("[]foo.FunctionalOption", foo.Opt1(), foo.Opt2())) +func FunctionalOptions(value ...interface{}) *FunctionalOptionsArgument { + return &FunctionalOptionsArgument{ + value: value, + } +} + // argumentMatcher performs custom argument matching, returning whether or // not the argument is matched by the expectation fixture function. type argumentMatcher struct { @@ -920,6 +963,29 @@ func (args Arguments) Diff(objects []interface{}) (string, int) { differences++ output = fmt.Sprintf("%s\t%d: FAIL: type %s != type %s - %s\n", output, i, reflect.TypeOf(t).Name(), reflect.TypeOf(actual).Name(), actualFmt) } + } else if reflect.TypeOf(expected) == reflect.TypeOf((*FunctionalOptionsArgument)(nil)) { + t := expected.(*FunctionalOptionsArgument).value + + var name string + tValue := reflect.ValueOf(t) + if tValue.Len() > 0 { + name = "[]" + reflect.TypeOf(tValue.Index(0).Interface()).String() + } + + tName := reflect.TypeOf(t).Name() + if name != reflect.TypeOf(actual).String() && tValue.Len() != 0 { + differences++ + output = fmt.Sprintf("%s\t%d: FAIL: type %s != type %s - %s\n", output, i, tName, reflect.TypeOf(actual).Name(), actualFmt) + } else { + if ef, af := assertOpts(t, actual); ef == "" && af == "" { + // match + output = fmt.Sprintf("%s\t%d: PASS: %s == %s\n", output, i, tName, tName) + } else { + // not match + differences++ + output = fmt.Sprintf("%s\t%d: FAIL: %s != %s\n", output, i, af, ef) + } + } } else { // normal checking @@ -1096,3 +1162,65 @@ var spewConfig = spew.ConfigState{ type tHelper interface { Helper() } + +func assertOpts(expected, actual interface{}) (expectedFmt, actualFmt string) { + expectedOpts := reflect.ValueOf(expected) + actualOpts := reflect.ValueOf(actual) + var expectedNames []string + for i := 0; i < expectedOpts.Len(); i++ { + expectedNames = append(expectedNames, funcName(expectedOpts.Index(i).Interface())) + } + var actualNames []string + for i := 0; i < actualOpts.Len(); i++ { + actualNames = append(actualNames, funcName(actualOpts.Index(i).Interface())) + } + if !assert.ObjectsAreEqual(expectedNames, actualNames) { + expectedFmt = fmt.Sprintf("%v", expectedNames) + actualFmt = fmt.Sprintf("%v", actualNames) + return + } + + for i := 0; i < expectedOpts.Len(); i++ { + expectedOpt := expectedOpts.Index(i).Interface() + actualOpt := actualOpts.Index(i).Interface() + + expectedFunc := expectedNames[i] + actualFunc := actualNames[i] + if expectedFunc != actualFunc { + expectedFmt = expectedFunc + actualFmt = actualFunc + return + } + + ot := reflect.TypeOf(expectedOpt) + var expectedValues []reflect.Value + var actualValues []reflect.Value + if ot.NumIn() == 0 { + return + } + + for i := 0; i < ot.NumIn(); i++ { + vt := ot.In(i).Elem() + expectedValues = append(expectedValues, reflect.New(vt)) + actualValues = append(actualValues, reflect.New(vt)) + } + + reflect.ValueOf(expectedOpt).Call(expectedValues) + reflect.ValueOf(actualOpt).Call(actualValues) + + for i := 0; i < ot.NumIn(); i++ { + if !assert.ObjectsAreEqual(expectedValues[i].Interface(), actualValues[i].Interface()) { + expectedFmt = fmt.Sprintf("%s %+v", expectedNames[i], expectedValues[i].Interface()) + actualFmt = fmt.Sprintf("%s %+v", expectedNames[i], actualValues[i].Interface()) + return + } + } + } + + return "", "" +} + +func funcName(opt interface{}) string { + n := runtime.FuncForPC(reflect.ValueOf(opt).Pointer()).Name() + return strings.TrimSuffix(path.Base(n), path.Ext(n)) +} diff --git a/vendor/github.com/stretchr/testify/require/doc.go b/vendor/github.com/stretchr/testify/require/doc.go index 169de39221..9684347245 100644 --- a/vendor/github.com/stretchr/testify/require/doc.go +++ b/vendor/github.com/stretchr/testify/require/doc.go @@ -1,24 +1,25 @@ // Package require implements the same assertions as the `assert` package but // stops test execution when a test fails. // -// Example Usage +// # Example Usage // // The following is a complete example using require in a standard test function: -// import ( -// "testing" -// "github.com/stretchr/testify/require" -// ) // -// func TestSomething(t *testing.T) { +// import ( +// "testing" +// "github.com/stretchr/testify/require" +// ) // -// var a string = "Hello" -// var b string = "Hello" +// func TestSomething(t *testing.T) { // -// require.Equal(t, a, b, "The two words should be the same.") +// var a string = "Hello" +// var b string = "Hello" // -// } +// require.Equal(t, a, b, "The two words should be the same.") // -// Assertions +// } +// +// # Assertions // // The `require` package have same global functions as in the `assert` package, // but instead of returning a boolean result they call `t.FailNow()`. diff --git a/vendor/github.com/stretchr/testify/require/require.go b/vendor/github.com/stretchr/testify/require/require.go index 880853f5a2..63f8521476 100644 --- a/vendor/github.com/stretchr/testify/require/require.go +++ b/vendor/github.com/stretchr/testify/require/require.go @@ -37,9 +37,9 @@ func Conditionf(t TestingT, comp assert.Comparison, msg string, args ...interfac // Contains asserts that the specified string, list(array, slice...) or map contains the // specified substring or element. // -// assert.Contains(t, "Hello World", "World") -// assert.Contains(t, ["Hello", "World"], "World") -// assert.Contains(t, {"Hello": "World"}, "Hello") +// assert.Contains(t, "Hello World", "World") +// assert.Contains(t, ["Hello", "World"], "World") +// assert.Contains(t, {"Hello": "World"}, "Hello") func Contains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -53,9 +53,9 @@ func Contains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...int // Containsf asserts that the specified string, list(array, slice...) or map contains the // specified substring or element. // -// assert.Containsf(t, "Hello World", "World", "error message %s", "formatted") -// assert.Containsf(t, ["Hello", "World"], "World", "error message %s", "formatted") -// assert.Containsf(t, {"Hello": "World"}, "Hello", "error message %s", "formatted") +// assert.Containsf(t, "Hello World", "World", "error message %s", "formatted") +// assert.Containsf(t, ["Hello", "World"], "World", "error message %s", "formatted") +// assert.Containsf(t, {"Hello": "World"}, "Hello", "error message %s", "formatted") func Containsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -123,7 +123,7 @@ func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string // Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either // a slice or a channel with len == 0. // -// assert.Empty(t, obj) +// assert.Empty(t, obj) func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -137,7 +137,7 @@ func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) { // Emptyf asserts that the specified object is empty. I.e. nil, "", false, 0 or either // a slice or a channel with len == 0. // -// assert.Emptyf(t, obj, "error message %s", "formatted") +// assert.Emptyf(t, obj, "error message %s", "formatted") func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -150,7 +150,7 @@ func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) { // Equal asserts that two objects are equal. // -// assert.Equal(t, 123, 123) +// assert.Equal(t, 123, 123) // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). Function equality @@ -168,8 +168,8 @@ func Equal(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...i // EqualError asserts that a function returned an error (i.e. not `nil`) // and that it is equal to the provided error. // -// actualObj, err := SomeFunction() -// assert.EqualError(t, err, expectedErrorString) +// actualObj, err := SomeFunction() +// assert.EqualError(t, err, expectedErrorString) func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -183,8 +183,8 @@ func EqualError(t TestingT, theError error, errString string, msgAndArgs ...inte // EqualErrorf asserts that a function returned an error (i.e. not `nil`) // and that it is equal to the provided error. // -// actualObj, err := SomeFunction() -// assert.EqualErrorf(t, err, expectedErrorString, "error message %s", "formatted") +// actualObj, err := SomeFunction() +// assert.EqualErrorf(t, err, expectedErrorString, "error message %s", "formatted") func EqualErrorf(t TestingT, theError error, errString string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -195,10 +195,50 @@ func EqualErrorf(t TestingT, theError error, errString string, msg string, args t.FailNow() } +// EqualExportedValues asserts that the types of two objects are equal and their public +// fields are also equal. This is useful for comparing structs that have private fields +// that could potentially differ. +// +// type S struct { +// Exported int +// notExported int +// } +// assert.EqualExportedValues(t, S{1, 2}, S{1, 3}) => true +// assert.EqualExportedValues(t, S{1, 2}, S{2, 3}) => false +func EqualExportedValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if assert.EqualExportedValues(t, expected, actual, msgAndArgs...) { + return + } + t.FailNow() +} + +// EqualExportedValuesf asserts that the types of two objects are equal and their public +// fields are also equal. This is useful for comparing structs that have private fields +// that could potentially differ. +// +// type S struct { +// Exported int +// notExported int +// } +// assert.EqualExportedValuesf(t, S{1, 2}, S{1, 3}, "error message %s", "formatted") => true +// assert.EqualExportedValuesf(t, S{1, 2}, S{2, 3}, "error message %s", "formatted") => false +func EqualExportedValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if assert.EqualExportedValuesf(t, expected, actual, msg, args...) { + return + } + t.FailNow() +} + // EqualValues asserts that two objects are equal or convertable to the same types // and equal. // -// assert.EqualValues(t, uint32(123), int32(123)) +// assert.EqualValues(t, uint32(123), int32(123)) func EqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -212,7 +252,7 @@ func EqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArg // EqualValuesf asserts that two objects are equal or convertable to the same types // and equal. // -// assert.EqualValuesf(t, uint32(123), int32(123), "error message %s", "formatted") +// assert.EqualValuesf(t, uint32(123), int32(123), "error message %s", "formatted") func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -225,7 +265,7 @@ func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg stri // Equalf asserts that two objects are equal. // -// assert.Equalf(t, 123, 123, "error message %s", "formatted") +// assert.Equalf(t, 123, 123, "error message %s", "formatted") // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). Function equality @@ -242,10 +282,10 @@ func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, ar // Error asserts that a function returned an error (i.e. not `nil`). // -// actualObj, err := SomeFunction() -// if assert.Error(t, err) { -// assert.Equal(t, expectedError, err) -// } +// actualObj, err := SomeFunction() +// if assert.Error(t, err) { +// assert.Equal(t, expectedError, err) +// } func Error(t TestingT, err error, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -283,8 +323,8 @@ func ErrorAsf(t TestingT, err error, target interface{}, msg string, args ...int // ErrorContains asserts that a function returned an error (i.e. not `nil`) // and that the error contains the specified substring. // -// actualObj, err := SomeFunction() -// assert.ErrorContains(t, err, expectedErrorSubString) +// actualObj, err := SomeFunction() +// assert.ErrorContains(t, err, expectedErrorSubString) func ErrorContains(t TestingT, theError error, contains string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -298,8 +338,8 @@ func ErrorContains(t TestingT, theError error, contains string, msgAndArgs ...in // ErrorContainsf asserts that a function returned an error (i.e. not `nil`) // and that the error contains the specified substring. // -// actualObj, err := SomeFunction() -// assert.ErrorContainsf(t, err, expectedErrorSubString, "error message %s", "formatted") +// actualObj, err := SomeFunction() +// assert.ErrorContainsf(t, err, expectedErrorSubString, "error message %s", "formatted") func ErrorContainsf(t TestingT, theError error, contains string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -336,10 +376,10 @@ func ErrorIsf(t TestingT, err error, target error, msg string, args ...interface // Errorf asserts that a function returned an error (i.e. not `nil`). // -// actualObj, err := SomeFunction() -// if assert.Errorf(t, err, "error message %s", "formatted") { -// assert.Equal(t, expectedErrorf, err) -// } +// actualObj, err := SomeFunction() +// if assert.Errorf(t, err, "error message %s", "formatted") { +// assert.Equal(t, expectedErrorf, err) +// } func Errorf(t TestingT, err error, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -353,7 +393,7 @@ func Errorf(t TestingT, err error, msg string, args ...interface{}) { // Eventually asserts that given condition will be met in waitFor time, // periodically checking target function each tick. // -// assert.Eventually(t, func() bool { return true; }, time.Second, 10*time.Millisecond) +// assert.Eventually(t, func() bool { return true; }, time.Second, 10*time.Millisecond) func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -364,10 +404,66 @@ func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick t t.FailNow() } +// EventuallyWithT asserts that given condition will be met in waitFor time, +// periodically checking target function each tick. In contrast to Eventually, +// it supplies a CollectT to the condition function, so that the condition +// function can use the CollectT to call other assertions. +// The condition is considered "met" if no errors are raised in a tick. +// The supplied CollectT collects all errors from one tick (if there are any). +// If the condition is not met before waitFor, the collected errors of +// the last tick are copied to t. +// +// externalValue := false +// go func() { +// time.Sleep(8*time.Second) +// externalValue = true +// }() +// assert.EventuallyWithT(t, func(c *assert.CollectT) { +// // add assertions as needed; any assertion failure will fail the current tick +// assert.True(c, externalValue, "expected 'externalValue' to be true") +// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") +func EventuallyWithT(t TestingT, condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if assert.EventuallyWithT(t, condition, waitFor, tick, msgAndArgs...) { + return + } + t.FailNow() +} + +// EventuallyWithTf asserts that given condition will be met in waitFor time, +// periodically checking target function each tick. In contrast to Eventually, +// it supplies a CollectT to the condition function, so that the condition +// function can use the CollectT to call other assertions. +// The condition is considered "met" if no errors are raised in a tick. +// The supplied CollectT collects all errors from one tick (if there are any). +// If the condition is not met before waitFor, the collected errors of +// the last tick are copied to t. +// +// externalValue := false +// go func() { +// time.Sleep(8*time.Second) +// externalValue = true +// }() +// assert.EventuallyWithTf(t, func(c *assert.CollectT, "error message %s", "formatted") { +// // add assertions as needed; any assertion failure will fail the current tick +// assert.True(c, externalValue, "expected 'externalValue' to be true") +// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") +func EventuallyWithTf(t TestingT, condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if assert.EventuallyWithTf(t, condition, waitFor, tick, msg, args...) { + return + } + t.FailNow() +} + // Eventuallyf asserts that given condition will be met in waitFor time, // periodically checking target function each tick. // -// assert.Eventuallyf(t, func() bool { return true; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") +// assert.Eventuallyf(t, func() bool { return true; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") func Eventuallyf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -380,7 +476,7 @@ func Eventuallyf(t TestingT, condition func() bool, waitFor time.Duration, tick // Exactly asserts that two objects are equal in value and type. // -// assert.Exactly(t, int32(123), int64(123)) +// assert.Exactly(t, int32(123), int64(123)) func Exactly(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -393,7 +489,7 @@ func Exactly(t TestingT, expected interface{}, actual interface{}, msgAndArgs .. // Exactlyf asserts that two objects are equal in value and type. // -// assert.Exactlyf(t, int32(123), int64(123), "error message %s", "formatted") +// assert.Exactlyf(t, int32(123), int64(123), "error message %s", "formatted") func Exactlyf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -450,7 +546,7 @@ func Failf(t TestingT, failureMessage string, msg string, args ...interface{}) { // False asserts that the specified value is false. // -// assert.False(t, myBool) +// assert.False(t, myBool) func False(t TestingT, value bool, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -463,7 +559,7 @@ func False(t TestingT, value bool, msgAndArgs ...interface{}) { // Falsef asserts that the specified value is false. // -// assert.Falsef(t, myBool, "error message %s", "formatted") +// assert.Falsef(t, myBool, "error message %s", "formatted") func Falsef(t TestingT, value bool, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -500,9 +596,9 @@ func FileExistsf(t TestingT, path string, msg string, args ...interface{}) { // Greater asserts that the first element is greater than the second // -// assert.Greater(t, 2, 1) -// assert.Greater(t, float64(2), float64(1)) -// assert.Greater(t, "b", "a") +// assert.Greater(t, 2, 1) +// assert.Greater(t, float64(2), float64(1)) +// assert.Greater(t, "b", "a") func Greater(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -515,10 +611,10 @@ func Greater(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface // GreaterOrEqual asserts that the first element is greater than or equal to the second // -// assert.GreaterOrEqual(t, 2, 1) -// assert.GreaterOrEqual(t, 2, 2) -// assert.GreaterOrEqual(t, "b", "a") -// assert.GreaterOrEqual(t, "b", "b") +// assert.GreaterOrEqual(t, 2, 1) +// assert.GreaterOrEqual(t, 2, 2) +// assert.GreaterOrEqual(t, "b", "a") +// assert.GreaterOrEqual(t, "b", "b") func GreaterOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -531,10 +627,10 @@ func GreaterOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...in // GreaterOrEqualf asserts that the first element is greater than or equal to the second // -// assert.GreaterOrEqualf(t, 2, 1, "error message %s", "formatted") -// assert.GreaterOrEqualf(t, 2, 2, "error message %s", "formatted") -// assert.GreaterOrEqualf(t, "b", "a", "error message %s", "formatted") -// assert.GreaterOrEqualf(t, "b", "b", "error message %s", "formatted") +// assert.GreaterOrEqualf(t, 2, 1, "error message %s", "formatted") +// assert.GreaterOrEqualf(t, 2, 2, "error message %s", "formatted") +// assert.GreaterOrEqualf(t, "b", "a", "error message %s", "formatted") +// assert.GreaterOrEqualf(t, "b", "b", "error message %s", "formatted") func GreaterOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -547,9 +643,9 @@ func GreaterOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, arg // Greaterf asserts that the first element is greater than the second // -// assert.Greaterf(t, 2, 1, "error message %s", "formatted") -// assert.Greaterf(t, float64(2), float64(1), "error message %s", "formatted") -// assert.Greaterf(t, "b", "a", "error message %s", "formatted") +// assert.Greaterf(t, 2, 1, "error message %s", "formatted") +// assert.Greaterf(t, float64(2), float64(1), "error message %s", "formatted") +// assert.Greaterf(t, "b", "a", "error message %s", "formatted") func Greaterf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -563,7 +659,7 @@ func Greaterf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...in // HTTPBodyContains asserts that a specified handler returns a // body that contains a string. // -// assert.HTTPBodyContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") +// assert.HTTPBodyContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") // // Returns whether the assertion was successful (true) or not (false). func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) { @@ -579,7 +675,7 @@ func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method string, url s // HTTPBodyContainsf asserts that a specified handler returns a // body that contains a string. // -// assert.HTTPBodyContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") +// assert.HTTPBodyContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) { @@ -595,7 +691,7 @@ func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url // HTTPBodyNotContains asserts that a specified handler returns a // body that does not contain a string. // -// assert.HTTPBodyNotContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") +// assert.HTTPBodyNotContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") // // Returns whether the assertion was successful (true) or not (false). func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) { @@ -611,7 +707,7 @@ func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method string, ur // HTTPBodyNotContainsf asserts that a specified handler returns a // body that does not contain a string. // -// assert.HTTPBodyNotContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") +// assert.HTTPBodyNotContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) { @@ -626,7 +722,7 @@ func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, u // HTTPError asserts that a specified handler returns an error status code. // -// assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). func HTTPError(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { @@ -641,7 +737,7 @@ func HTTPError(t TestingT, handler http.HandlerFunc, method string, url string, // HTTPErrorf asserts that a specified handler returns an error status code. // -// assert.HTTPErrorf(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// assert.HTTPErrorf(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { @@ -656,7 +752,7 @@ func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, // HTTPRedirect asserts that a specified handler returns a redirect status code. // -// assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). func HTTPRedirect(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { @@ -671,7 +767,7 @@ func HTTPRedirect(t TestingT, handler http.HandlerFunc, method string, url strin // HTTPRedirectf asserts that a specified handler returns a redirect status code. // -// assert.HTTPRedirectf(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// assert.HTTPRedirectf(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { @@ -686,7 +782,7 @@ func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url stri // HTTPStatusCode asserts that a specified handler returns a specified status code. // -// assert.HTTPStatusCode(t, myHandler, "GET", "/notImplemented", nil, 501) +// assert.HTTPStatusCode(t, myHandler, "GET", "/notImplemented", nil, 501) // // Returns whether the assertion was successful (true) or not (false). func HTTPStatusCode(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msgAndArgs ...interface{}) { @@ -701,7 +797,7 @@ func HTTPStatusCode(t TestingT, handler http.HandlerFunc, method string, url str // HTTPStatusCodef asserts that a specified handler returns a specified status code. // -// assert.HTTPStatusCodef(t, myHandler, "GET", "/notImplemented", nil, 501, "error message %s", "formatted") +// assert.HTTPStatusCodef(t, myHandler, "GET", "/notImplemented", nil, 501, "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). func HTTPStatusCodef(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msg string, args ...interface{}) { @@ -716,7 +812,7 @@ func HTTPStatusCodef(t TestingT, handler http.HandlerFunc, method string, url st // HTTPSuccess asserts that a specified handler returns a success status code. // -// assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil) +// assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil) // // Returns whether the assertion was successful (true) or not (false). func HTTPSuccess(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { @@ -731,7 +827,7 @@ func HTTPSuccess(t TestingT, handler http.HandlerFunc, method string, url string // HTTPSuccessf asserts that a specified handler returns a success status code. // -// assert.HTTPSuccessf(t, myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted") +// assert.HTTPSuccessf(t, myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { @@ -746,7 +842,7 @@ func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url strin // Implements asserts that an object is implemented by the specified interface. // -// assert.Implements(t, (*MyInterface)(nil), new(MyObject)) +// assert.Implements(t, (*MyInterface)(nil), new(MyObject)) func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -759,7 +855,7 @@ func Implements(t TestingT, interfaceObject interface{}, object interface{}, msg // Implementsf asserts that an object is implemented by the specified interface. // -// assert.Implementsf(t, (*MyInterface)(nil), new(MyObject), "error message %s", "formatted") +// assert.Implementsf(t, (*MyInterface)(nil), new(MyObject), "error message %s", "formatted") func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -772,7 +868,7 @@ func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, ms // InDelta asserts that the two numerals are within delta of each other. // -// assert.InDelta(t, math.Pi, 22/7.0, 0.01) +// assert.InDelta(t, math.Pi, 22/7.0, 0.01) func InDelta(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -829,7 +925,7 @@ func InDeltaSlicef(t TestingT, expected interface{}, actual interface{}, delta f // InDeltaf asserts that the two numerals are within delta of each other. // -// assert.InDeltaf(t, math.Pi, 22/7.0, 0.01, "error message %s", "formatted") +// assert.InDeltaf(t, math.Pi, 22/7.0, 0.01, "error message %s", "formatted") func InDeltaf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -886,9 +982,9 @@ func InEpsilonf(t TestingT, expected interface{}, actual interface{}, epsilon fl // IsDecreasing asserts that the collection is decreasing // -// assert.IsDecreasing(t, []int{2, 1, 0}) -// assert.IsDecreasing(t, []float{2, 1}) -// assert.IsDecreasing(t, []string{"b", "a"}) +// assert.IsDecreasing(t, []int{2, 1, 0}) +// assert.IsDecreasing(t, []float{2, 1}) +// assert.IsDecreasing(t, []string{"b", "a"}) func IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -901,9 +997,9 @@ func IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { // IsDecreasingf asserts that the collection is decreasing // -// assert.IsDecreasingf(t, []int{2, 1, 0}, "error message %s", "formatted") -// assert.IsDecreasingf(t, []float{2, 1}, "error message %s", "formatted") -// assert.IsDecreasingf(t, []string{"b", "a"}, "error message %s", "formatted") +// assert.IsDecreasingf(t, []int{2, 1, 0}, "error message %s", "formatted") +// assert.IsDecreasingf(t, []float{2, 1}, "error message %s", "formatted") +// assert.IsDecreasingf(t, []string{"b", "a"}, "error message %s", "formatted") func IsDecreasingf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -916,9 +1012,9 @@ func IsDecreasingf(t TestingT, object interface{}, msg string, args ...interface // IsIncreasing asserts that the collection is increasing // -// assert.IsIncreasing(t, []int{1, 2, 3}) -// assert.IsIncreasing(t, []float{1, 2}) -// assert.IsIncreasing(t, []string{"a", "b"}) +// assert.IsIncreasing(t, []int{1, 2, 3}) +// assert.IsIncreasing(t, []float{1, 2}) +// assert.IsIncreasing(t, []string{"a", "b"}) func IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -931,9 +1027,9 @@ func IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { // IsIncreasingf asserts that the collection is increasing // -// assert.IsIncreasingf(t, []int{1, 2, 3}, "error message %s", "formatted") -// assert.IsIncreasingf(t, []float{1, 2}, "error message %s", "formatted") -// assert.IsIncreasingf(t, []string{"a", "b"}, "error message %s", "formatted") +// assert.IsIncreasingf(t, []int{1, 2, 3}, "error message %s", "formatted") +// assert.IsIncreasingf(t, []float{1, 2}, "error message %s", "formatted") +// assert.IsIncreasingf(t, []string{"a", "b"}, "error message %s", "formatted") func IsIncreasingf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -946,9 +1042,9 @@ func IsIncreasingf(t TestingT, object interface{}, msg string, args ...interface // IsNonDecreasing asserts that the collection is not decreasing // -// assert.IsNonDecreasing(t, []int{1, 1, 2}) -// assert.IsNonDecreasing(t, []float{1, 2}) -// assert.IsNonDecreasing(t, []string{"a", "b"}) +// assert.IsNonDecreasing(t, []int{1, 1, 2}) +// assert.IsNonDecreasing(t, []float{1, 2}) +// assert.IsNonDecreasing(t, []string{"a", "b"}) func IsNonDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -961,9 +1057,9 @@ func IsNonDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) // IsNonDecreasingf asserts that the collection is not decreasing // -// assert.IsNonDecreasingf(t, []int{1, 1, 2}, "error message %s", "formatted") -// assert.IsNonDecreasingf(t, []float{1, 2}, "error message %s", "formatted") -// assert.IsNonDecreasingf(t, []string{"a", "b"}, "error message %s", "formatted") +// assert.IsNonDecreasingf(t, []int{1, 1, 2}, "error message %s", "formatted") +// assert.IsNonDecreasingf(t, []float{1, 2}, "error message %s", "formatted") +// assert.IsNonDecreasingf(t, []string{"a", "b"}, "error message %s", "formatted") func IsNonDecreasingf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -976,9 +1072,9 @@ func IsNonDecreasingf(t TestingT, object interface{}, msg string, args ...interf // IsNonIncreasing asserts that the collection is not increasing // -// assert.IsNonIncreasing(t, []int{2, 1, 1}) -// assert.IsNonIncreasing(t, []float{2, 1}) -// assert.IsNonIncreasing(t, []string{"b", "a"}) +// assert.IsNonIncreasing(t, []int{2, 1, 1}) +// assert.IsNonIncreasing(t, []float{2, 1}) +// assert.IsNonIncreasing(t, []string{"b", "a"}) func IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -991,9 +1087,9 @@ func IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) // IsNonIncreasingf asserts that the collection is not increasing // -// assert.IsNonIncreasingf(t, []int{2, 1, 1}, "error message %s", "formatted") -// assert.IsNonIncreasingf(t, []float{2, 1}, "error message %s", "formatted") -// assert.IsNonIncreasingf(t, []string{"b", "a"}, "error message %s", "formatted") +// assert.IsNonIncreasingf(t, []int{2, 1, 1}, "error message %s", "formatted") +// assert.IsNonIncreasingf(t, []float{2, 1}, "error message %s", "formatted") +// assert.IsNonIncreasingf(t, []string{"b", "a"}, "error message %s", "formatted") func IsNonIncreasingf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1028,7 +1124,7 @@ func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg strin // JSONEq asserts that two JSON strings are equivalent. // -// assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) +// assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1041,7 +1137,7 @@ func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{ // JSONEqf asserts that two JSON strings are equivalent. // -// assert.JSONEqf(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted") +// assert.JSONEqf(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted") func JSONEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1055,7 +1151,7 @@ func JSONEqf(t TestingT, expected string, actual string, msg string, args ...int // Len asserts that the specified object has specific length. // Len also fails if the object has a type that len() not accept. // -// assert.Len(t, mySlice, 3) +// assert.Len(t, mySlice, 3) func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1069,7 +1165,7 @@ func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) // Lenf asserts that the specified object has specific length. // Lenf also fails if the object has a type that len() not accept. // -// assert.Lenf(t, mySlice, 3, "error message %s", "formatted") +// assert.Lenf(t, mySlice, 3, "error message %s", "formatted") func Lenf(t TestingT, object interface{}, length int, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1082,9 +1178,9 @@ func Lenf(t TestingT, object interface{}, length int, msg string, args ...interf // Less asserts that the first element is less than the second // -// assert.Less(t, 1, 2) -// assert.Less(t, float64(1), float64(2)) -// assert.Less(t, "a", "b") +// assert.Less(t, 1, 2) +// assert.Less(t, float64(1), float64(2)) +// assert.Less(t, "a", "b") func Less(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1097,10 +1193,10 @@ func Less(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) // LessOrEqual asserts that the first element is less than or equal to the second // -// assert.LessOrEqual(t, 1, 2) -// assert.LessOrEqual(t, 2, 2) -// assert.LessOrEqual(t, "a", "b") -// assert.LessOrEqual(t, "b", "b") +// assert.LessOrEqual(t, 1, 2) +// assert.LessOrEqual(t, 2, 2) +// assert.LessOrEqual(t, "a", "b") +// assert.LessOrEqual(t, "b", "b") func LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1113,10 +1209,10 @@ func LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...inter // LessOrEqualf asserts that the first element is less than or equal to the second // -// assert.LessOrEqualf(t, 1, 2, "error message %s", "formatted") -// assert.LessOrEqualf(t, 2, 2, "error message %s", "formatted") -// assert.LessOrEqualf(t, "a", "b", "error message %s", "formatted") -// assert.LessOrEqualf(t, "b", "b", "error message %s", "formatted") +// assert.LessOrEqualf(t, 1, 2, "error message %s", "formatted") +// assert.LessOrEqualf(t, 2, 2, "error message %s", "formatted") +// assert.LessOrEqualf(t, "a", "b", "error message %s", "formatted") +// assert.LessOrEqualf(t, "b", "b", "error message %s", "formatted") func LessOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1129,9 +1225,9 @@ func LessOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args . // Lessf asserts that the first element is less than the second // -// assert.Lessf(t, 1, 2, "error message %s", "formatted") -// assert.Lessf(t, float64(1), float64(2), "error message %s", "formatted") -// assert.Lessf(t, "a", "b", "error message %s", "formatted") +// assert.Lessf(t, 1, 2, "error message %s", "formatted") +// assert.Lessf(t, float64(1), float64(2), "error message %s", "formatted") +// assert.Lessf(t, "a", "b", "error message %s", "formatted") func Lessf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1144,8 +1240,8 @@ func Lessf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...inter // Negative asserts that the specified element is negative // -// assert.Negative(t, -1) -// assert.Negative(t, -1.23) +// assert.Negative(t, -1) +// assert.Negative(t, -1.23) func Negative(t TestingT, e interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1158,8 +1254,8 @@ func Negative(t TestingT, e interface{}, msgAndArgs ...interface{}) { // Negativef asserts that the specified element is negative // -// assert.Negativef(t, -1, "error message %s", "formatted") -// assert.Negativef(t, -1.23, "error message %s", "formatted") +// assert.Negativef(t, -1, "error message %s", "formatted") +// assert.Negativef(t, -1.23, "error message %s", "formatted") func Negativef(t TestingT, e interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1173,7 +1269,7 @@ func Negativef(t TestingT, e interface{}, msg string, args ...interface{}) { // Never asserts that the given condition doesn't satisfy in waitFor time, // periodically checking the target function each tick. // -// assert.Never(t, func() bool { return false; }, time.Second, 10*time.Millisecond) +// assert.Never(t, func() bool { return false; }, time.Second, 10*time.Millisecond) func Never(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1187,7 +1283,7 @@ func Never(t TestingT, condition func() bool, waitFor time.Duration, tick time.D // Neverf asserts that the given condition doesn't satisfy in waitFor time, // periodically checking the target function each tick. // -// assert.Neverf(t, func() bool { return false; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") +// assert.Neverf(t, func() bool { return false; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") func Neverf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1200,7 +1296,7 @@ func Neverf(t TestingT, condition func() bool, waitFor time.Duration, tick time. // Nil asserts that the specified object is nil. // -// assert.Nil(t, err) +// assert.Nil(t, err) func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1213,7 +1309,7 @@ func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) { // Nilf asserts that the specified object is nil. // -// assert.Nilf(t, err, "error message %s", "formatted") +// assert.Nilf(t, err, "error message %s", "formatted") func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1250,10 +1346,10 @@ func NoDirExistsf(t TestingT, path string, msg string, args ...interface{}) { // NoError asserts that a function returned no error (i.e. `nil`). // -// actualObj, err := SomeFunction() -// if assert.NoError(t, err) { -// assert.Equal(t, expectedObj, actualObj) -// } +// actualObj, err := SomeFunction() +// if assert.NoError(t, err) { +// assert.Equal(t, expectedObj, actualObj) +// } func NoError(t TestingT, err error, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1266,10 +1362,10 @@ func NoError(t TestingT, err error, msgAndArgs ...interface{}) { // NoErrorf asserts that a function returned no error (i.e. `nil`). // -// actualObj, err := SomeFunction() -// if assert.NoErrorf(t, err, "error message %s", "formatted") { -// assert.Equal(t, expectedObj, actualObj) -// } +// actualObj, err := SomeFunction() +// if assert.NoErrorf(t, err, "error message %s", "formatted") { +// assert.Equal(t, expectedObj, actualObj) +// } func NoErrorf(t TestingT, err error, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1307,9 +1403,9 @@ func NoFileExistsf(t TestingT, path string, msg string, args ...interface{}) { // NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the // specified substring or element. // -// assert.NotContains(t, "Hello World", "Earth") -// assert.NotContains(t, ["Hello", "World"], "Earth") -// assert.NotContains(t, {"Hello": "World"}, "Earth") +// assert.NotContains(t, "Hello World", "Earth") +// assert.NotContains(t, ["Hello", "World"], "Earth") +// assert.NotContains(t, {"Hello": "World"}, "Earth") func NotContains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1323,9 +1419,9 @@ func NotContains(t TestingT, s interface{}, contains interface{}, msgAndArgs ... // NotContainsf asserts that the specified string, list(array, slice...) or map does NOT contain the // specified substring or element. // -// assert.NotContainsf(t, "Hello World", "Earth", "error message %s", "formatted") -// assert.NotContainsf(t, ["Hello", "World"], "Earth", "error message %s", "formatted") -// assert.NotContainsf(t, {"Hello": "World"}, "Earth", "error message %s", "formatted") +// assert.NotContainsf(t, "Hello World", "Earth", "error message %s", "formatted") +// assert.NotContainsf(t, ["Hello", "World"], "Earth", "error message %s", "formatted") +// assert.NotContainsf(t, {"Hello": "World"}, "Earth", "error message %s", "formatted") func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1339,9 +1435,9 @@ func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, a // NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either // a slice or a channel with len == 0. // -// if assert.NotEmpty(t, obj) { -// assert.Equal(t, "two", obj[1]) -// } +// if assert.NotEmpty(t, obj) { +// assert.Equal(t, "two", obj[1]) +// } func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1355,9 +1451,9 @@ func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) { // NotEmptyf asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either // a slice or a channel with len == 0. // -// if assert.NotEmptyf(t, obj, "error message %s", "formatted") { -// assert.Equal(t, "two", obj[1]) -// } +// if assert.NotEmptyf(t, obj, "error message %s", "formatted") { +// assert.Equal(t, "two", obj[1]) +// } func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1370,7 +1466,7 @@ func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) // NotEqual asserts that the specified values are NOT equal. // -// assert.NotEqual(t, obj1, obj2) +// assert.NotEqual(t, obj1, obj2) // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). @@ -1386,7 +1482,7 @@ func NotEqual(t TestingT, expected interface{}, actual interface{}, msgAndArgs . // NotEqualValues asserts that two objects are not equal even when converted to the same type // -// assert.NotEqualValues(t, obj1, obj2) +// assert.NotEqualValues(t, obj1, obj2) func NotEqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1399,7 +1495,7 @@ func NotEqualValues(t TestingT, expected interface{}, actual interface{}, msgAnd // NotEqualValuesf asserts that two objects are not equal even when converted to the same type // -// assert.NotEqualValuesf(t, obj1, obj2, "error message %s", "formatted") +// assert.NotEqualValuesf(t, obj1, obj2, "error message %s", "formatted") func NotEqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1412,7 +1508,7 @@ func NotEqualValuesf(t TestingT, expected interface{}, actual interface{}, msg s // NotEqualf asserts that the specified values are NOT equal. // -// assert.NotEqualf(t, obj1, obj2, "error message %s", "formatted") +// assert.NotEqualf(t, obj1, obj2, "error message %s", "formatted") // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). @@ -1452,7 +1548,7 @@ func NotErrorIsf(t TestingT, err error, target error, msg string, args ...interf // NotNil asserts that the specified object is not nil. // -// assert.NotNil(t, err) +// assert.NotNil(t, err) func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1465,7 +1561,7 @@ func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) { // NotNilf asserts that the specified object is not nil. // -// assert.NotNilf(t, err, "error message %s", "formatted") +// assert.NotNilf(t, err, "error message %s", "formatted") func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1478,7 +1574,7 @@ func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) { // NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. // -// assert.NotPanics(t, func(){ RemainCalm() }) +// assert.NotPanics(t, func(){ RemainCalm() }) func NotPanics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1491,7 +1587,7 @@ func NotPanics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) { // NotPanicsf asserts that the code inside the specified PanicTestFunc does NOT panic. // -// assert.NotPanicsf(t, func(){ RemainCalm() }, "error message %s", "formatted") +// assert.NotPanicsf(t, func(){ RemainCalm() }, "error message %s", "formatted") func NotPanicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1504,8 +1600,8 @@ func NotPanicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interfac // NotRegexp asserts that a specified regexp does not match a string. // -// assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting") -// assert.NotRegexp(t, "^start", "it's not starting") +// assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting") +// assert.NotRegexp(t, "^start", "it's not starting") func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1518,8 +1614,8 @@ func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interf // NotRegexpf asserts that a specified regexp does not match a string. // -// assert.NotRegexpf(t, regexp.MustCompile("starts"), "it's starting", "error message %s", "formatted") -// assert.NotRegexpf(t, "^start", "it's not starting", "error message %s", "formatted") +// assert.NotRegexpf(t, regexp.MustCompile("starts"), "it's starting", "error message %s", "formatted") +// assert.NotRegexpf(t, "^start", "it's not starting", "error message %s", "formatted") func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1532,7 +1628,7 @@ func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args .. // NotSame asserts that two pointers do not reference the same object. // -// assert.NotSame(t, ptr1, ptr2) +// assert.NotSame(t, ptr1, ptr2) // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. @@ -1548,7 +1644,7 @@ func NotSame(t TestingT, expected interface{}, actual interface{}, msgAndArgs .. // NotSamef asserts that two pointers do not reference the same object. // -// assert.NotSamef(t, ptr1, ptr2, "error message %s", "formatted") +// assert.NotSamef(t, ptr1, ptr2, "error message %s", "formatted") // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. @@ -1565,7 +1661,7 @@ func NotSamef(t TestingT, expected interface{}, actual interface{}, msg string, // NotSubset asserts that the specified list(array, slice...) contains not all // elements given in the specified subset(array, slice...). // -// assert.NotSubset(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]") +// assert.NotSubset(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]") func NotSubset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1579,7 +1675,7 @@ func NotSubset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...i // NotSubsetf asserts that the specified list(array, slice...) contains not all // elements given in the specified subset(array, slice...). // -// assert.NotSubsetf(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted") +// assert.NotSubsetf(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted") func NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1614,7 +1710,7 @@ func NotZerof(t TestingT, i interface{}, msg string, args ...interface{}) { // Panics asserts that the code inside the specified PanicTestFunc panics. // -// assert.Panics(t, func(){ GoCrazy() }) +// assert.Panics(t, func(){ GoCrazy() }) func Panics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1629,7 +1725,7 @@ func Panics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) { // panics, and that the recovered panic value is an error that satisfies the // EqualError comparison. // -// assert.PanicsWithError(t, "crazy error", func(){ GoCrazy() }) +// assert.PanicsWithError(t, "crazy error", func(){ GoCrazy() }) func PanicsWithError(t TestingT, errString string, f assert.PanicTestFunc, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1644,7 +1740,7 @@ func PanicsWithError(t TestingT, errString string, f assert.PanicTestFunc, msgAn // panics, and that the recovered panic value is an error that satisfies the // EqualError comparison. // -// assert.PanicsWithErrorf(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") +// assert.PanicsWithErrorf(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") func PanicsWithErrorf(t TestingT, errString string, f assert.PanicTestFunc, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1658,7 +1754,7 @@ func PanicsWithErrorf(t TestingT, errString string, f assert.PanicTestFunc, msg // PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that // the recovered panic value equals the expected panic value. // -// assert.PanicsWithValue(t, "crazy error", func(){ GoCrazy() }) +// assert.PanicsWithValue(t, "crazy error", func(){ GoCrazy() }) func PanicsWithValue(t TestingT, expected interface{}, f assert.PanicTestFunc, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1672,7 +1768,7 @@ func PanicsWithValue(t TestingT, expected interface{}, f assert.PanicTestFunc, m // PanicsWithValuef asserts that the code inside the specified PanicTestFunc panics, and that // the recovered panic value equals the expected panic value. // -// assert.PanicsWithValuef(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") +// assert.PanicsWithValuef(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") func PanicsWithValuef(t TestingT, expected interface{}, f assert.PanicTestFunc, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1685,7 +1781,7 @@ func PanicsWithValuef(t TestingT, expected interface{}, f assert.PanicTestFunc, // Panicsf asserts that the code inside the specified PanicTestFunc panics. // -// assert.Panicsf(t, func(){ GoCrazy() }, "error message %s", "formatted") +// assert.Panicsf(t, func(){ GoCrazy() }, "error message %s", "formatted") func Panicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1698,8 +1794,8 @@ func Panicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interface{} // Positive asserts that the specified element is positive // -// assert.Positive(t, 1) -// assert.Positive(t, 1.23) +// assert.Positive(t, 1) +// assert.Positive(t, 1.23) func Positive(t TestingT, e interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1712,8 +1808,8 @@ func Positive(t TestingT, e interface{}, msgAndArgs ...interface{}) { // Positivef asserts that the specified element is positive // -// assert.Positivef(t, 1, "error message %s", "formatted") -// assert.Positivef(t, 1.23, "error message %s", "formatted") +// assert.Positivef(t, 1, "error message %s", "formatted") +// assert.Positivef(t, 1.23, "error message %s", "formatted") func Positivef(t TestingT, e interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1726,8 +1822,8 @@ func Positivef(t TestingT, e interface{}, msg string, args ...interface{}) { // Regexp asserts that a specified regexp matches a string. // -// assert.Regexp(t, regexp.MustCompile("start"), "it's starting") -// assert.Regexp(t, "start...$", "it's not starting") +// assert.Regexp(t, regexp.MustCompile("start"), "it's starting") +// assert.Regexp(t, "start...$", "it's not starting") func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1740,8 +1836,8 @@ func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface // Regexpf asserts that a specified regexp matches a string. // -// assert.Regexpf(t, regexp.MustCompile("start"), "it's starting", "error message %s", "formatted") -// assert.Regexpf(t, "start...$", "it's not starting", "error message %s", "formatted") +// assert.Regexpf(t, regexp.MustCompile("start"), "it's starting", "error message %s", "formatted") +// assert.Regexpf(t, "start...$", "it's not starting", "error message %s", "formatted") func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1754,7 +1850,7 @@ func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...in // Same asserts that two pointers reference the same object. // -// assert.Same(t, ptr1, ptr2) +// assert.Same(t, ptr1, ptr2) // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. @@ -1770,7 +1866,7 @@ func Same(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...in // Samef asserts that two pointers reference the same object. // -// assert.Samef(t, ptr1, ptr2, "error message %s", "formatted") +// assert.Samef(t, ptr1, ptr2, "error message %s", "formatted") // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. @@ -1787,7 +1883,7 @@ func Samef(t TestingT, expected interface{}, actual interface{}, msg string, arg // Subset asserts that the specified list(array, slice...) contains all // elements given in the specified subset(array, slice...). // -// assert.Subset(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]") +// assert.Subset(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]") func Subset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1801,7 +1897,7 @@ func Subset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...inte // Subsetf asserts that the specified list(array, slice...) contains all // elements given in the specified subset(array, slice...). // -// assert.Subsetf(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted") +// assert.Subsetf(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted") func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1814,7 +1910,7 @@ func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args // True asserts that the specified value is true. // -// assert.True(t, myBool) +// assert.True(t, myBool) func True(t TestingT, value bool, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1827,7 +1923,7 @@ func True(t TestingT, value bool, msgAndArgs ...interface{}) { // Truef asserts that the specified value is true. // -// assert.Truef(t, myBool, "error message %s", "formatted") +// assert.Truef(t, myBool, "error message %s", "formatted") func Truef(t TestingT, value bool, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1840,7 +1936,7 @@ func Truef(t TestingT, value bool, msg string, args ...interface{}) { // WithinDuration asserts that the two times are within duration delta of each other. // -// assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second) +// assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second) func WithinDuration(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1853,7 +1949,7 @@ func WithinDuration(t TestingT, expected time.Time, actual time.Time, delta time // WithinDurationf asserts that the two times are within duration delta of each other. // -// assert.WithinDurationf(t, time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted") +// assert.WithinDurationf(t, time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted") func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1866,7 +1962,7 @@ func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta tim // WithinRange asserts that a time is within a time range (inclusive). // -// assert.WithinRange(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second)) +// assert.WithinRange(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second)) func WithinRange(t TestingT, actual time.Time, start time.Time, end time.Time, msgAndArgs ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() @@ -1879,7 +1975,7 @@ func WithinRange(t TestingT, actual time.Time, start time.Time, end time.Time, m // WithinRangef asserts that a time is within a time range (inclusive). // -// assert.WithinRangef(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), "error message %s", "formatted") +// assert.WithinRangef(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), "error message %s", "formatted") func WithinRangef(t TestingT, actual time.Time, start time.Time, end time.Time, msg string, args ...interface{}) { if h, ok := t.(tHelper); ok { h.Helper() diff --git a/vendor/github.com/stretchr/testify/require/require_forward.go b/vendor/github.com/stretchr/testify/require/require_forward.go index 960bf6f2ca..3b5b09330a 100644 --- a/vendor/github.com/stretchr/testify/require/require_forward.go +++ b/vendor/github.com/stretchr/testify/require/require_forward.go @@ -31,9 +31,9 @@ func (a *Assertions) Conditionf(comp assert.Comparison, msg string, args ...inte // Contains asserts that the specified string, list(array, slice...) or map contains the // specified substring or element. // -// a.Contains("Hello World", "World") -// a.Contains(["Hello", "World"], "World") -// a.Contains({"Hello": "World"}, "Hello") +// a.Contains("Hello World", "World") +// a.Contains(["Hello", "World"], "World") +// a.Contains({"Hello": "World"}, "Hello") func (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -44,9 +44,9 @@ func (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs .. // Containsf asserts that the specified string, list(array, slice...) or map contains the // specified substring or element. // -// a.Containsf("Hello World", "World", "error message %s", "formatted") -// a.Containsf(["Hello", "World"], "World", "error message %s", "formatted") -// a.Containsf({"Hello": "World"}, "Hello", "error message %s", "formatted") +// a.Containsf("Hello World", "World", "error message %s", "formatted") +// a.Containsf(["Hello", "World"], "World", "error message %s", "formatted") +// a.Containsf({"Hello": "World"}, "Hello", "error message %s", "formatted") func (a *Assertions) Containsf(s interface{}, contains interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -99,7 +99,7 @@ func (a *Assertions) ElementsMatchf(listA interface{}, listB interface{}, msg st // Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either // a slice or a channel with len == 0. // -// a.Empty(obj) +// a.Empty(obj) func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -110,7 +110,7 @@ func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) { // Emptyf asserts that the specified object is empty. I.e. nil, "", false, 0 or either // a slice or a channel with len == 0. // -// a.Emptyf(obj, "error message %s", "formatted") +// a.Emptyf(obj, "error message %s", "formatted") func (a *Assertions) Emptyf(object interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -120,7 +120,7 @@ func (a *Assertions) Emptyf(object interface{}, msg string, args ...interface{}) // Equal asserts that two objects are equal. // -// a.Equal(123, 123) +// a.Equal(123, 123) // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). Function equality @@ -135,8 +135,8 @@ func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs // EqualError asserts that a function returned an error (i.e. not `nil`) // and that it is equal to the provided error. // -// actualObj, err := SomeFunction() -// a.EqualError(err, expectedErrorString) +// actualObj, err := SomeFunction() +// a.EqualError(err, expectedErrorString) func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -147,8 +147,8 @@ func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ... // EqualErrorf asserts that a function returned an error (i.e. not `nil`) // and that it is equal to the provided error. // -// actualObj, err := SomeFunction() -// a.EqualErrorf(err, expectedErrorString, "error message %s", "formatted") +// actualObj, err := SomeFunction() +// a.EqualErrorf(err, expectedErrorString, "error message %s", "formatted") func (a *Assertions) EqualErrorf(theError error, errString string, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -156,10 +156,44 @@ func (a *Assertions) EqualErrorf(theError error, errString string, msg string, a EqualErrorf(a.t, theError, errString, msg, args...) } +// EqualExportedValues asserts that the types of two objects are equal and their public +// fields are also equal. This is useful for comparing structs that have private fields +// that could potentially differ. +// +// type S struct { +// Exported int +// notExported int +// } +// a.EqualExportedValues(S{1, 2}, S{1, 3}) => true +// a.EqualExportedValues(S{1, 2}, S{2, 3}) => false +func (a *Assertions) EqualExportedValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + EqualExportedValues(a.t, expected, actual, msgAndArgs...) +} + +// EqualExportedValuesf asserts that the types of two objects are equal and their public +// fields are also equal. This is useful for comparing structs that have private fields +// that could potentially differ. +// +// type S struct { +// Exported int +// notExported int +// } +// a.EqualExportedValuesf(S{1, 2}, S{1, 3}, "error message %s", "formatted") => true +// a.EqualExportedValuesf(S{1, 2}, S{2, 3}, "error message %s", "formatted") => false +func (a *Assertions) EqualExportedValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + EqualExportedValuesf(a.t, expected, actual, msg, args...) +} + // EqualValues asserts that two objects are equal or convertable to the same types // and equal. // -// a.EqualValues(uint32(123), int32(123)) +// a.EqualValues(uint32(123), int32(123)) func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -170,7 +204,7 @@ func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAn // EqualValuesf asserts that two objects are equal or convertable to the same types // and equal. // -// a.EqualValuesf(uint32(123), int32(123), "error message %s", "formatted") +// a.EqualValuesf(uint32(123), int32(123), "error message %s", "formatted") func (a *Assertions) EqualValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -180,7 +214,7 @@ func (a *Assertions) EqualValuesf(expected interface{}, actual interface{}, msg // Equalf asserts that two objects are equal. // -// a.Equalf(123, 123, "error message %s", "formatted") +// a.Equalf(123, 123, "error message %s", "formatted") // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). Function equality @@ -194,10 +228,10 @@ func (a *Assertions) Equalf(expected interface{}, actual interface{}, msg string // Error asserts that a function returned an error (i.e. not `nil`). // -// actualObj, err := SomeFunction() -// if a.Error(err) { -// assert.Equal(t, expectedError, err) -// } +// actualObj, err := SomeFunction() +// if a.Error(err) { +// assert.Equal(t, expectedError, err) +// } func (a *Assertions) Error(err error, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -226,8 +260,8 @@ func (a *Assertions) ErrorAsf(err error, target interface{}, msg string, args .. // ErrorContains asserts that a function returned an error (i.e. not `nil`) // and that the error contains the specified substring. // -// actualObj, err := SomeFunction() -// a.ErrorContains(err, expectedErrorSubString) +// actualObj, err := SomeFunction() +// a.ErrorContains(err, expectedErrorSubString) func (a *Assertions) ErrorContains(theError error, contains string, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -238,8 +272,8 @@ func (a *Assertions) ErrorContains(theError error, contains string, msgAndArgs . // ErrorContainsf asserts that a function returned an error (i.e. not `nil`) // and that the error contains the specified substring. // -// actualObj, err := SomeFunction() -// a.ErrorContainsf(err, expectedErrorSubString, "error message %s", "formatted") +// actualObj, err := SomeFunction() +// a.ErrorContainsf(err, expectedErrorSubString, "error message %s", "formatted") func (a *Assertions) ErrorContainsf(theError error, contains string, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -267,10 +301,10 @@ func (a *Assertions) ErrorIsf(err error, target error, msg string, args ...inter // Errorf asserts that a function returned an error (i.e. not `nil`). // -// actualObj, err := SomeFunction() -// if a.Errorf(err, "error message %s", "formatted") { -// assert.Equal(t, expectedErrorf, err) -// } +// actualObj, err := SomeFunction() +// if a.Errorf(err, "error message %s", "formatted") { +// assert.Equal(t, expectedErrorf, err) +// } func (a *Assertions) Errorf(err error, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -281,7 +315,7 @@ func (a *Assertions) Errorf(err error, msg string, args ...interface{}) { // Eventually asserts that given condition will be met in waitFor time, // periodically checking target function each tick. // -// a.Eventually(func() bool { return true; }, time.Second, 10*time.Millisecond) +// a.Eventually(func() bool { return true; }, time.Second, 10*time.Millisecond) func (a *Assertions) Eventually(condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -289,10 +323,60 @@ func (a *Assertions) Eventually(condition func() bool, waitFor time.Duration, ti Eventually(a.t, condition, waitFor, tick, msgAndArgs...) } +// EventuallyWithT asserts that given condition will be met in waitFor time, +// periodically checking target function each tick. In contrast to Eventually, +// it supplies a CollectT to the condition function, so that the condition +// function can use the CollectT to call other assertions. +// The condition is considered "met" if no errors are raised in a tick. +// The supplied CollectT collects all errors from one tick (if there are any). +// If the condition is not met before waitFor, the collected errors of +// the last tick are copied to t. +// +// externalValue := false +// go func() { +// time.Sleep(8*time.Second) +// externalValue = true +// }() +// a.EventuallyWithT(func(c *assert.CollectT) { +// // add assertions as needed; any assertion failure will fail the current tick +// assert.True(c, externalValue, "expected 'externalValue' to be true") +// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") +func (a *Assertions) EventuallyWithT(condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + EventuallyWithT(a.t, condition, waitFor, tick, msgAndArgs...) +} + +// EventuallyWithTf asserts that given condition will be met in waitFor time, +// periodically checking target function each tick. In contrast to Eventually, +// it supplies a CollectT to the condition function, so that the condition +// function can use the CollectT to call other assertions. +// The condition is considered "met" if no errors are raised in a tick. +// The supplied CollectT collects all errors from one tick (if there are any). +// If the condition is not met before waitFor, the collected errors of +// the last tick are copied to t. +// +// externalValue := false +// go func() { +// time.Sleep(8*time.Second) +// externalValue = true +// }() +// a.EventuallyWithTf(func(c *assert.CollectT, "error message %s", "formatted") { +// // add assertions as needed; any assertion failure will fail the current tick +// assert.True(c, externalValue, "expected 'externalValue' to be true") +// }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") +func (a *Assertions) EventuallyWithTf(condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + EventuallyWithTf(a.t, condition, waitFor, tick, msg, args...) +} + // Eventuallyf asserts that given condition will be met in waitFor time, // periodically checking target function each tick. // -// a.Eventuallyf(func() bool { return true; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") +// a.Eventuallyf(func() bool { return true; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") func (a *Assertions) Eventuallyf(condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -302,7 +386,7 @@ func (a *Assertions) Eventuallyf(condition func() bool, waitFor time.Duration, t // Exactly asserts that two objects are equal in value and type. // -// a.Exactly(int32(123), int64(123)) +// a.Exactly(int32(123), int64(123)) func (a *Assertions) Exactly(expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -312,7 +396,7 @@ func (a *Assertions) Exactly(expected interface{}, actual interface{}, msgAndArg // Exactlyf asserts that two objects are equal in value and type. // -// a.Exactlyf(int32(123), int64(123), "error message %s", "formatted") +// a.Exactlyf(int32(123), int64(123), "error message %s", "formatted") func (a *Assertions) Exactlyf(expected interface{}, actual interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -354,7 +438,7 @@ func (a *Assertions) Failf(failureMessage string, msg string, args ...interface{ // False asserts that the specified value is false. // -// a.False(myBool) +// a.False(myBool) func (a *Assertions) False(value bool, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -364,7 +448,7 @@ func (a *Assertions) False(value bool, msgAndArgs ...interface{}) { // Falsef asserts that the specified value is false. // -// a.Falsef(myBool, "error message %s", "formatted") +// a.Falsef(myBool, "error message %s", "formatted") func (a *Assertions) Falsef(value bool, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -392,9 +476,9 @@ func (a *Assertions) FileExistsf(path string, msg string, args ...interface{}) { // Greater asserts that the first element is greater than the second // -// a.Greater(2, 1) -// a.Greater(float64(2), float64(1)) -// a.Greater("b", "a") +// a.Greater(2, 1) +// a.Greater(float64(2), float64(1)) +// a.Greater("b", "a") func (a *Assertions) Greater(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -404,10 +488,10 @@ func (a *Assertions) Greater(e1 interface{}, e2 interface{}, msgAndArgs ...inter // GreaterOrEqual asserts that the first element is greater than or equal to the second // -// a.GreaterOrEqual(2, 1) -// a.GreaterOrEqual(2, 2) -// a.GreaterOrEqual("b", "a") -// a.GreaterOrEqual("b", "b") +// a.GreaterOrEqual(2, 1) +// a.GreaterOrEqual(2, 2) +// a.GreaterOrEqual("b", "a") +// a.GreaterOrEqual("b", "b") func (a *Assertions) GreaterOrEqual(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -417,10 +501,10 @@ func (a *Assertions) GreaterOrEqual(e1 interface{}, e2 interface{}, msgAndArgs . // GreaterOrEqualf asserts that the first element is greater than or equal to the second // -// a.GreaterOrEqualf(2, 1, "error message %s", "formatted") -// a.GreaterOrEqualf(2, 2, "error message %s", "formatted") -// a.GreaterOrEqualf("b", "a", "error message %s", "formatted") -// a.GreaterOrEqualf("b", "b", "error message %s", "formatted") +// a.GreaterOrEqualf(2, 1, "error message %s", "formatted") +// a.GreaterOrEqualf(2, 2, "error message %s", "formatted") +// a.GreaterOrEqualf("b", "a", "error message %s", "formatted") +// a.GreaterOrEqualf("b", "b", "error message %s", "formatted") func (a *Assertions) GreaterOrEqualf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -430,9 +514,9 @@ func (a *Assertions) GreaterOrEqualf(e1 interface{}, e2 interface{}, msg string, // Greaterf asserts that the first element is greater than the second // -// a.Greaterf(2, 1, "error message %s", "formatted") -// a.Greaterf(float64(2), float64(1), "error message %s", "formatted") -// a.Greaterf("b", "a", "error message %s", "formatted") +// a.Greaterf(2, 1, "error message %s", "formatted") +// a.Greaterf(float64(2), float64(1), "error message %s", "formatted") +// a.Greaterf("b", "a", "error message %s", "formatted") func (a *Assertions) Greaterf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -443,7 +527,7 @@ func (a *Assertions) Greaterf(e1 interface{}, e2 interface{}, msg string, args . // HTTPBodyContains asserts that a specified handler returns a // body that contains a string. // -// a.HTTPBodyContains(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") +// a.HTTPBodyContains(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) { @@ -456,7 +540,7 @@ func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, u // HTTPBodyContainsf asserts that a specified handler returns a // body that contains a string. // -// a.HTTPBodyContainsf(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") +// a.HTTPBodyContainsf(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPBodyContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) { @@ -469,7 +553,7 @@ func (a *Assertions) HTTPBodyContainsf(handler http.HandlerFunc, method string, // HTTPBodyNotContains asserts that a specified handler returns a // body that does not contain a string. // -// a.HTTPBodyNotContains(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") +// a.HTTPBodyNotContains(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) { @@ -482,7 +566,7 @@ func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string // HTTPBodyNotContainsf asserts that a specified handler returns a // body that does not contain a string. // -// a.HTTPBodyNotContainsf(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") +// a.HTTPBodyNotContainsf(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPBodyNotContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) { @@ -494,7 +578,7 @@ func (a *Assertions) HTTPBodyNotContainsf(handler http.HandlerFunc, method strin // HTTPError asserts that a specified handler returns an error status code. // -// a.HTTPError(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// a.HTTPError(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { @@ -506,7 +590,7 @@ func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url stri // HTTPErrorf asserts that a specified handler returns an error status code. // -// a.HTTPErrorf(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// a.HTTPErrorf(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPErrorf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { @@ -518,7 +602,7 @@ func (a *Assertions) HTTPErrorf(handler http.HandlerFunc, method string, url str // HTTPRedirect asserts that a specified handler returns a redirect status code. // -// a.HTTPRedirect(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// a.HTTPRedirect(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { @@ -530,7 +614,7 @@ func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url s // HTTPRedirectf asserts that a specified handler returns a redirect status code. // -// a.HTTPRedirectf(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// a.HTTPRedirectf(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPRedirectf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { @@ -542,7 +626,7 @@ func (a *Assertions) HTTPRedirectf(handler http.HandlerFunc, method string, url // HTTPStatusCode asserts that a specified handler returns a specified status code. // -// a.HTTPStatusCode(myHandler, "GET", "/notImplemented", nil, 501) +// a.HTTPStatusCode(myHandler, "GET", "/notImplemented", nil, 501) // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPStatusCode(handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msgAndArgs ...interface{}) { @@ -554,7 +638,7 @@ func (a *Assertions) HTTPStatusCode(handler http.HandlerFunc, method string, url // HTTPStatusCodef asserts that a specified handler returns a specified status code. // -// a.HTTPStatusCodef(myHandler, "GET", "/notImplemented", nil, 501, "error message %s", "formatted") +// a.HTTPStatusCodef(myHandler, "GET", "/notImplemented", nil, 501, "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPStatusCodef(handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msg string, args ...interface{}) { @@ -566,7 +650,7 @@ func (a *Assertions) HTTPStatusCodef(handler http.HandlerFunc, method string, ur // HTTPSuccess asserts that a specified handler returns a success status code. // -// a.HTTPSuccess(myHandler, "POST", "http://www.google.com", nil) +// a.HTTPSuccess(myHandler, "POST", "http://www.google.com", nil) // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) { @@ -578,7 +662,7 @@ func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url st // HTTPSuccessf asserts that a specified handler returns a success status code. // -// a.HTTPSuccessf(myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted") +// a.HTTPSuccessf(myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted") // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPSuccessf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) { @@ -590,7 +674,7 @@ func (a *Assertions) HTTPSuccessf(handler http.HandlerFunc, method string, url s // Implements asserts that an object is implemented by the specified interface. // -// a.Implements((*MyInterface)(nil), new(MyObject)) +// a.Implements((*MyInterface)(nil), new(MyObject)) func (a *Assertions) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -600,7 +684,7 @@ func (a *Assertions) Implements(interfaceObject interface{}, object interface{}, // Implementsf asserts that an object is implemented by the specified interface. // -// a.Implementsf((*MyInterface)(nil), new(MyObject), "error message %s", "formatted") +// a.Implementsf((*MyInterface)(nil), new(MyObject), "error message %s", "formatted") func (a *Assertions) Implementsf(interfaceObject interface{}, object interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -610,7 +694,7 @@ func (a *Assertions) Implementsf(interfaceObject interface{}, object interface{} // InDelta asserts that the two numerals are within delta of each other. // -// a.InDelta(math.Pi, 22/7.0, 0.01) +// a.InDelta(math.Pi, 22/7.0, 0.01) func (a *Assertions) InDelta(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -652,7 +736,7 @@ func (a *Assertions) InDeltaSlicef(expected interface{}, actual interface{}, del // InDeltaf asserts that the two numerals are within delta of each other. // -// a.InDeltaf(math.Pi, 22/7.0, 0.01, "error message %s", "formatted") +// a.InDeltaf(math.Pi, 22/7.0, 0.01, "error message %s", "formatted") func (a *Assertions) InDeltaf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -694,9 +778,9 @@ func (a *Assertions) InEpsilonf(expected interface{}, actual interface{}, epsilo // IsDecreasing asserts that the collection is decreasing // -// a.IsDecreasing([]int{2, 1, 0}) -// a.IsDecreasing([]float{2, 1}) -// a.IsDecreasing([]string{"b", "a"}) +// a.IsDecreasing([]int{2, 1, 0}) +// a.IsDecreasing([]float{2, 1}) +// a.IsDecreasing([]string{"b", "a"}) func (a *Assertions) IsDecreasing(object interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -706,9 +790,9 @@ func (a *Assertions) IsDecreasing(object interface{}, msgAndArgs ...interface{}) // IsDecreasingf asserts that the collection is decreasing // -// a.IsDecreasingf([]int{2, 1, 0}, "error message %s", "formatted") -// a.IsDecreasingf([]float{2, 1}, "error message %s", "formatted") -// a.IsDecreasingf([]string{"b", "a"}, "error message %s", "formatted") +// a.IsDecreasingf([]int{2, 1, 0}, "error message %s", "formatted") +// a.IsDecreasingf([]float{2, 1}, "error message %s", "formatted") +// a.IsDecreasingf([]string{"b", "a"}, "error message %s", "formatted") func (a *Assertions) IsDecreasingf(object interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -718,9 +802,9 @@ func (a *Assertions) IsDecreasingf(object interface{}, msg string, args ...inter // IsIncreasing asserts that the collection is increasing // -// a.IsIncreasing([]int{1, 2, 3}) -// a.IsIncreasing([]float{1, 2}) -// a.IsIncreasing([]string{"a", "b"}) +// a.IsIncreasing([]int{1, 2, 3}) +// a.IsIncreasing([]float{1, 2}) +// a.IsIncreasing([]string{"a", "b"}) func (a *Assertions) IsIncreasing(object interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -730,9 +814,9 @@ func (a *Assertions) IsIncreasing(object interface{}, msgAndArgs ...interface{}) // IsIncreasingf asserts that the collection is increasing // -// a.IsIncreasingf([]int{1, 2, 3}, "error message %s", "formatted") -// a.IsIncreasingf([]float{1, 2}, "error message %s", "formatted") -// a.IsIncreasingf([]string{"a", "b"}, "error message %s", "formatted") +// a.IsIncreasingf([]int{1, 2, 3}, "error message %s", "formatted") +// a.IsIncreasingf([]float{1, 2}, "error message %s", "formatted") +// a.IsIncreasingf([]string{"a", "b"}, "error message %s", "formatted") func (a *Assertions) IsIncreasingf(object interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -742,9 +826,9 @@ func (a *Assertions) IsIncreasingf(object interface{}, msg string, args ...inter // IsNonDecreasing asserts that the collection is not decreasing // -// a.IsNonDecreasing([]int{1, 1, 2}) -// a.IsNonDecreasing([]float{1, 2}) -// a.IsNonDecreasing([]string{"a", "b"}) +// a.IsNonDecreasing([]int{1, 1, 2}) +// a.IsNonDecreasing([]float{1, 2}) +// a.IsNonDecreasing([]string{"a", "b"}) func (a *Assertions) IsNonDecreasing(object interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -754,9 +838,9 @@ func (a *Assertions) IsNonDecreasing(object interface{}, msgAndArgs ...interface // IsNonDecreasingf asserts that the collection is not decreasing // -// a.IsNonDecreasingf([]int{1, 1, 2}, "error message %s", "formatted") -// a.IsNonDecreasingf([]float{1, 2}, "error message %s", "formatted") -// a.IsNonDecreasingf([]string{"a", "b"}, "error message %s", "formatted") +// a.IsNonDecreasingf([]int{1, 1, 2}, "error message %s", "formatted") +// a.IsNonDecreasingf([]float{1, 2}, "error message %s", "formatted") +// a.IsNonDecreasingf([]string{"a", "b"}, "error message %s", "formatted") func (a *Assertions) IsNonDecreasingf(object interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -766,9 +850,9 @@ func (a *Assertions) IsNonDecreasingf(object interface{}, msg string, args ...in // IsNonIncreasing asserts that the collection is not increasing // -// a.IsNonIncreasing([]int{2, 1, 1}) -// a.IsNonIncreasing([]float{2, 1}) -// a.IsNonIncreasing([]string{"b", "a"}) +// a.IsNonIncreasing([]int{2, 1, 1}) +// a.IsNonIncreasing([]float{2, 1}) +// a.IsNonIncreasing([]string{"b", "a"}) func (a *Assertions) IsNonIncreasing(object interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -778,9 +862,9 @@ func (a *Assertions) IsNonIncreasing(object interface{}, msgAndArgs ...interface // IsNonIncreasingf asserts that the collection is not increasing // -// a.IsNonIncreasingf([]int{2, 1, 1}, "error message %s", "formatted") -// a.IsNonIncreasingf([]float{2, 1}, "error message %s", "formatted") -// a.IsNonIncreasingf([]string{"b", "a"}, "error message %s", "formatted") +// a.IsNonIncreasingf([]int{2, 1, 1}, "error message %s", "formatted") +// a.IsNonIncreasingf([]float{2, 1}, "error message %s", "formatted") +// a.IsNonIncreasingf([]string{"b", "a"}, "error message %s", "formatted") func (a *Assertions) IsNonIncreasingf(object interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -806,7 +890,7 @@ func (a *Assertions) IsTypef(expectedType interface{}, object interface{}, msg s // JSONEq asserts that two JSON strings are equivalent. // -// a.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) +// a.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -816,7 +900,7 @@ func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interf // JSONEqf asserts that two JSON strings are equivalent. // -// a.JSONEqf(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted") +// a.JSONEqf(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted") func (a *Assertions) JSONEqf(expected string, actual string, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -827,7 +911,7 @@ func (a *Assertions) JSONEqf(expected string, actual string, msg string, args .. // Len asserts that the specified object has specific length. // Len also fails if the object has a type that len() not accept. // -// a.Len(mySlice, 3) +// a.Len(mySlice, 3) func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -838,7 +922,7 @@ func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface // Lenf asserts that the specified object has specific length. // Lenf also fails if the object has a type that len() not accept. // -// a.Lenf(mySlice, 3, "error message %s", "formatted") +// a.Lenf(mySlice, 3, "error message %s", "formatted") func (a *Assertions) Lenf(object interface{}, length int, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -848,9 +932,9 @@ func (a *Assertions) Lenf(object interface{}, length int, msg string, args ...in // Less asserts that the first element is less than the second // -// a.Less(1, 2) -// a.Less(float64(1), float64(2)) -// a.Less("a", "b") +// a.Less(1, 2) +// a.Less(float64(1), float64(2)) +// a.Less("a", "b") func (a *Assertions) Less(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -860,10 +944,10 @@ func (a *Assertions) Less(e1 interface{}, e2 interface{}, msgAndArgs ...interfac // LessOrEqual asserts that the first element is less than or equal to the second // -// a.LessOrEqual(1, 2) -// a.LessOrEqual(2, 2) -// a.LessOrEqual("a", "b") -// a.LessOrEqual("b", "b") +// a.LessOrEqual(1, 2) +// a.LessOrEqual(2, 2) +// a.LessOrEqual("a", "b") +// a.LessOrEqual("b", "b") func (a *Assertions) LessOrEqual(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -873,10 +957,10 @@ func (a *Assertions) LessOrEqual(e1 interface{}, e2 interface{}, msgAndArgs ...i // LessOrEqualf asserts that the first element is less than or equal to the second // -// a.LessOrEqualf(1, 2, "error message %s", "formatted") -// a.LessOrEqualf(2, 2, "error message %s", "formatted") -// a.LessOrEqualf("a", "b", "error message %s", "formatted") -// a.LessOrEqualf("b", "b", "error message %s", "formatted") +// a.LessOrEqualf(1, 2, "error message %s", "formatted") +// a.LessOrEqualf(2, 2, "error message %s", "formatted") +// a.LessOrEqualf("a", "b", "error message %s", "formatted") +// a.LessOrEqualf("b", "b", "error message %s", "formatted") func (a *Assertions) LessOrEqualf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -886,9 +970,9 @@ func (a *Assertions) LessOrEqualf(e1 interface{}, e2 interface{}, msg string, ar // Lessf asserts that the first element is less than the second // -// a.Lessf(1, 2, "error message %s", "formatted") -// a.Lessf(float64(1), float64(2), "error message %s", "formatted") -// a.Lessf("a", "b", "error message %s", "formatted") +// a.Lessf(1, 2, "error message %s", "formatted") +// a.Lessf(float64(1), float64(2), "error message %s", "formatted") +// a.Lessf("a", "b", "error message %s", "formatted") func (a *Assertions) Lessf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -898,8 +982,8 @@ func (a *Assertions) Lessf(e1 interface{}, e2 interface{}, msg string, args ...i // Negative asserts that the specified element is negative // -// a.Negative(-1) -// a.Negative(-1.23) +// a.Negative(-1) +// a.Negative(-1.23) func (a *Assertions) Negative(e interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -909,8 +993,8 @@ func (a *Assertions) Negative(e interface{}, msgAndArgs ...interface{}) { // Negativef asserts that the specified element is negative // -// a.Negativef(-1, "error message %s", "formatted") -// a.Negativef(-1.23, "error message %s", "formatted") +// a.Negativef(-1, "error message %s", "formatted") +// a.Negativef(-1.23, "error message %s", "formatted") func (a *Assertions) Negativef(e interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -921,7 +1005,7 @@ func (a *Assertions) Negativef(e interface{}, msg string, args ...interface{}) { // Never asserts that the given condition doesn't satisfy in waitFor time, // periodically checking the target function each tick. // -// a.Never(func() bool { return false; }, time.Second, 10*time.Millisecond) +// a.Never(func() bool { return false; }, time.Second, 10*time.Millisecond) func (a *Assertions) Never(condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -932,7 +1016,7 @@ func (a *Assertions) Never(condition func() bool, waitFor time.Duration, tick ti // Neverf asserts that the given condition doesn't satisfy in waitFor time, // periodically checking the target function each tick. // -// a.Neverf(func() bool { return false; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") +// a.Neverf(func() bool { return false; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") func (a *Assertions) Neverf(condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -942,7 +1026,7 @@ func (a *Assertions) Neverf(condition func() bool, waitFor time.Duration, tick t // Nil asserts that the specified object is nil. // -// a.Nil(err) +// a.Nil(err) func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -952,7 +1036,7 @@ func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) { // Nilf asserts that the specified object is nil. // -// a.Nilf(err, "error message %s", "formatted") +// a.Nilf(err, "error message %s", "formatted") func (a *Assertions) Nilf(object interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -980,10 +1064,10 @@ func (a *Assertions) NoDirExistsf(path string, msg string, args ...interface{}) // NoError asserts that a function returned no error (i.e. `nil`). // -// actualObj, err := SomeFunction() -// if a.NoError(err) { -// assert.Equal(t, expectedObj, actualObj) -// } +// actualObj, err := SomeFunction() +// if a.NoError(err) { +// assert.Equal(t, expectedObj, actualObj) +// } func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -993,10 +1077,10 @@ func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) { // NoErrorf asserts that a function returned no error (i.e. `nil`). // -// actualObj, err := SomeFunction() -// if a.NoErrorf(err, "error message %s", "formatted") { -// assert.Equal(t, expectedObj, actualObj) -// } +// actualObj, err := SomeFunction() +// if a.NoErrorf(err, "error message %s", "formatted") { +// assert.Equal(t, expectedObj, actualObj) +// } func (a *Assertions) NoErrorf(err error, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1025,9 +1109,9 @@ func (a *Assertions) NoFileExistsf(path string, msg string, args ...interface{}) // NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the // specified substring or element. // -// a.NotContains("Hello World", "Earth") -// a.NotContains(["Hello", "World"], "Earth") -// a.NotContains({"Hello": "World"}, "Earth") +// a.NotContains("Hello World", "Earth") +// a.NotContains(["Hello", "World"], "Earth") +// a.NotContains({"Hello": "World"}, "Earth") func (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1038,9 +1122,9 @@ func (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs // NotContainsf asserts that the specified string, list(array, slice...) or map does NOT contain the // specified substring or element. // -// a.NotContainsf("Hello World", "Earth", "error message %s", "formatted") -// a.NotContainsf(["Hello", "World"], "Earth", "error message %s", "formatted") -// a.NotContainsf({"Hello": "World"}, "Earth", "error message %s", "formatted") +// a.NotContainsf("Hello World", "Earth", "error message %s", "formatted") +// a.NotContainsf(["Hello", "World"], "Earth", "error message %s", "formatted") +// a.NotContainsf({"Hello": "World"}, "Earth", "error message %s", "formatted") func (a *Assertions) NotContainsf(s interface{}, contains interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1051,9 +1135,9 @@ func (a *Assertions) NotContainsf(s interface{}, contains interface{}, msg strin // NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either // a slice or a channel with len == 0. // -// if a.NotEmpty(obj) { -// assert.Equal(t, "two", obj[1]) -// } +// if a.NotEmpty(obj) { +// assert.Equal(t, "two", obj[1]) +// } func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1064,9 +1148,9 @@ func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) { // NotEmptyf asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either // a slice or a channel with len == 0. // -// if a.NotEmptyf(obj, "error message %s", "formatted") { -// assert.Equal(t, "two", obj[1]) -// } +// if a.NotEmptyf(obj, "error message %s", "formatted") { +// assert.Equal(t, "two", obj[1]) +// } func (a *Assertions) NotEmptyf(object interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1076,7 +1160,7 @@ func (a *Assertions) NotEmptyf(object interface{}, msg string, args ...interface // NotEqual asserts that the specified values are NOT equal. // -// a.NotEqual(obj1, obj2) +// a.NotEqual(obj1, obj2) // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). @@ -1089,7 +1173,7 @@ func (a *Assertions) NotEqual(expected interface{}, actual interface{}, msgAndAr // NotEqualValues asserts that two objects are not equal even when converted to the same type // -// a.NotEqualValues(obj1, obj2) +// a.NotEqualValues(obj1, obj2) func (a *Assertions) NotEqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1099,7 +1183,7 @@ func (a *Assertions) NotEqualValues(expected interface{}, actual interface{}, ms // NotEqualValuesf asserts that two objects are not equal even when converted to the same type // -// a.NotEqualValuesf(obj1, obj2, "error message %s", "formatted") +// a.NotEqualValuesf(obj1, obj2, "error message %s", "formatted") func (a *Assertions) NotEqualValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1109,7 +1193,7 @@ func (a *Assertions) NotEqualValuesf(expected interface{}, actual interface{}, m // NotEqualf asserts that the specified values are NOT equal. // -// a.NotEqualf(obj1, obj2, "error message %s", "formatted") +// a.NotEqualf(obj1, obj2, "error message %s", "formatted") // // Pointer variable equality is determined based on the equality of the // referenced values (as opposed to the memory addresses). @@ -1140,7 +1224,7 @@ func (a *Assertions) NotErrorIsf(err error, target error, msg string, args ...in // NotNil asserts that the specified object is not nil. // -// a.NotNil(err) +// a.NotNil(err) func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1150,7 +1234,7 @@ func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) { // NotNilf asserts that the specified object is not nil. // -// a.NotNilf(err, "error message %s", "formatted") +// a.NotNilf(err, "error message %s", "formatted") func (a *Assertions) NotNilf(object interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1160,7 +1244,7 @@ func (a *Assertions) NotNilf(object interface{}, msg string, args ...interface{} // NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. // -// a.NotPanics(func(){ RemainCalm() }) +// a.NotPanics(func(){ RemainCalm() }) func (a *Assertions) NotPanics(f assert.PanicTestFunc, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1170,7 +1254,7 @@ func (a *Assertions) NotPanics(f assert.PanicTestFunc, msgAndArgs ...interface{} // NotPanicsf asserts that the code inside the specified PanicTestFunc does NOT panic. // -// a.NotPanicsf(func(){ RemainCalm() }, "error message %s", "formatted") +// a.NotPanicsf(func(){ RemainCalm() }, "error message %s", "formatted") func (a *Assertions) NotPanicsf(f assert.PanicTestFunc, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1180,8 +1264,8 @@ func (a *Assertions) NotPanicsf(f assert.PanicTestFunc, msg string, args ...inte // NotRegexp asserts that a specified regexp does not match a string. // -// a.NotRegexp(regexp.MustCompile("starts"), "it's starting") -// a.NotRegexp("^start", "it's not starting") +// a.NotRegexp(regexp.MustCompile("starts"), "it's starting") +// a.NotRegexp("^start", "it's not starting") func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1191,8 +1275,8 @@ func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...in // NotRegexpf asserts that a specified regexp does not match a string. // -// a.NotRegexpf(regexp.MustCompile("starts"), "it's starting", "error message %s", "formatted") -// a.NotRegexpf("^start", "it's not starting", "error message %s", "formatted") +// a.NotRegexpf(regexp.MustCompile("starts"), "it's starting", "error message %s", "formatted") +// a.NotRegexpf("^start", "it's not starting", "error message %s", "formatted") func (a *Assertions) NotRegexpf(rx interface{}, str interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1202,7 +1286,7 @@ func (a *Assertions) NotRegexpf(rx interface{}, str interface{}, msg string, arg // NotSame asserts that two pointers do not reference the same object. // -// a.NotSame(ptr1, ptr2) +// a.NotSame(ptr1, ptr2) // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. @@ -1215,7 +1299,7 @@ func (a *Assertions) NotSame(expected interface{}, actual interface{}, msgAndArg // NotSamef asserts that two pointers do not reference the same object. // -// a.NotSamef(ptr1, ptr2, "error message %s", "formatted") +// a.NotSamef(ptr1, ptr2, "error message %s", "formatted") // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. @@ -1229,7 +1313,7 @@ func (a *Assertions) NotSamef(expected interface{}, actual interface{}, msg stri // NotSubset asserts that the specified list(array, slice...) contains not all // elements given in the specified subset(array, slice...). // -// a.NotSubset([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]") +// a.NotSubset([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]") func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1240,7 +1324,7 @@ func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs // NotSubsetf asserts that the specified list(array, slice...) contains not all // elements given in the specified subset(array, slice...). // -// a.NotSubsetf([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted") +// a.NotSubsetf([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted") func (a *Assertions) NotSubsetf(list interface{}, subset interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1266,7 +1350,7 @@ func (a *Assertions) NotZerof(i interface{}, msg string, args ...interface{}) { // Panics asserts that the code inside the specified PanicTestFunc panics. // -// a.Panics(func(){ GoCrazy() }) +// a.Panics(func(){ GoCrazy() }) func (a *Assertions) Panics(f assert.PanicTestFunc, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1278,7 +1362,7 @@ func (a *Assertions) Panics(f assert.PanicTestFunc, msgAndArgs ...interface{}) { // panics, and that the recovered panic value is an error that satisfies the // EqualError comparison. // -// a.PanicsWithError("crazy error", func(){ GoCrazy() }) +// a.PanicsWithError("crazy error", func(){ GoCrazy() }) func (a *Assertions) PanicsWithError(errString string, f assert.PanicTestFunc, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1290,7 +1374,7 @@ func (a *Assertions) PanicsWithError(errString string, f assert.PanicTestFunc, m // panics, and that the recovered panic value is an error that satisfies the // EqualError comparison. // -// a.PanicsWithErrorf("crazy error", func(){ GoCrazy() }, "error message %s", "formatted") +// a.PanicsWithErrorf("crazy error", func(){ GoCrazy() }, "error message %s", "formatted") func (a *Assertions) PanicsWithErrorf(errString string, f assert.PanicTestFunc, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1301,7 +1385,7 @@ func (a *Assertions) PanicsWithErrorf(errString string, f assert.PanicTestFunc, // PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that // the recovered panic value equals the expected panic value. // -// a.PanicsWithValue("crazy error", func(){ GoCrazy() }) +// a.PanicsWithValue("crazy error", func(){ GoCrazy() }) func (a *Assertions) PanicsWithValue(expected interface{}, f assert.PanicTestFunc, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1312,7 +1396,7 @@ func (a *Assertions) PanicsWithValue(expected interface{}, f assert.PanicTestFun // PanicsWithValuef asserts that the code inside the specified PanicTestFunc panics, and that // the recovered panic value equals the expected panic value. // -// a.PanicsWithValuef("crazy error", func(){ GoCrazy() }, "error message %s", "formatted") +// a.PanicsWithValuef("crazy error", func(){ GoCrazy() }, "error message %s", "formatted") func (a *Assertions) PanicsWithValuef(expected interface{}, f assert.PanicTestFunc, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1322,7 +1406,7 @@ func (a *Assertions) PanicsWithValuef(expected interface{}, f assert.PanicTestFu // Panicsf asserts that the code inside the specified PanicTestFunc panics. // -// a.Panicsf(func(){ GoCrazy() }, "error message %s", "formatted") +// a.Panicsf(func(){ GoCrazy() }, "error message %s", "formatted") func (a *Assertions) Panicsf(f assert.PanicTestFunc, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1332,8 +1416,8 @@ func (a *Assertions) Panicsf(f assert.PanicTestFunc, msg string, args ...interfa // Positive asserts that the specified element is positive // -// a.Positive(1) -// a.Positive(1.23) +// a.Positive(1) +// a.Positive(1.23) func (a *Assertions) Positive(e interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1343,8 +1427,8 @@ func (a *Assertions) Positive(e interface{}, msgAndArgs ...interface{}) { // Positivef asserts that the specified element is positive // -// a.Positivef(1, "error message %s", "formatted") -// a.Positivef(1.23, "error message %s", "formatted") +// a.Positivef(1, "error message %s", "formatted") +// a.Positivef(1.23, "error message %s", "formatted") func (a *Assertions) Positivef(e interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1354,8 +1438,8 @@ func (a *Assertions) Positivef(e interface{}, msg string, args ...interface{}) { // Regexp asserts that a specified regexp matches a string. // -// a.Regexp(regexp.MustCompile("start"), "it's starting") -// a.Regexp("start...$", "it's not starting") +// a.Regexp(regexp.MustCompile("start"), "it's starting") +// a.Regexp("start...$", "it's not starting") func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1365,8 +1449,8 @@ func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...inter // Regexpf asserts that a specified regexp matches a string. // -// a.Regexpf(regexp.MustCompile("start"), "it's starting", "error message %s", "formatted") -// a.Regexpf("start...$", "it's not starting", "error message %s", "formatted") +// a.Regexpf(regexp.MustCompile("start"), "it's starting", "error message %s", "formatted") +// a.Regexpf("start...$", "it's not starting", "error message %s", "formatted") func (a *Assertions) Regexpf(rx interface{}, str interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1376,7 +1460,7 @@ func (a *Assertions) Regexpf(rx interface{}, str interface{}, msg string, args . // Same asserts that two pointers reference the same object. // -// a.Same(ptr1, ptr2) +// a.Same(ptr1, ptr2) // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. @@ -1389,7 +1473,7 @@ func (a *Assertions) Same(expected interface{}, actual interface{}, msgAndArgs . // Samef asserts that two pointers reference the same object. // -// a.Samef(ptr1, ptr2, "error message %s", "formatted") +// a.Samef(ptr1, ptr2, "error message %s", "formatted") // // Both arguments must be pointer variables. Pointer variable sameness is // determined based on the equality of both type and value. @@ -1403,7 +1487,7 @@ func (a *Assertions) Samef(expected interface{}, actual interface{}, msg string, // Subset asserts that the specified list(array, slice...) contains all // elements given in the specified subset(array, slice...). // -// a.Subset([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]") +// a.Subset([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]") func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1414,7 +1498,7 @@ func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ... // Subsetf asserts that the specified list(array, slice...) contains all // elements given in the specified subset(array, slice...). // -// a.Subsetf([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted") +// a.Subsetf([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted") func (a *Assertions) Subsetf(list interface{}, subset interface{}, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1424,7 +1508,7 @@ func (a *Assertions) Subsetf(list interface{}, subset interface{}, msg string, a // True asserts that the specified value is true. // -// a.True(myBool) +// a.True(myBool) func (a *Assertions) True(value bool, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1434,7 +1518,7 @@ func (a *Assertions) True(value bool, msgAndArgs ...interface{}) { // Truef asserts that the specified value is true. // -// a.Truef(myBool, "error message %s", "formatted") +// a.Truef(myBool, "error message %s", "formatted") func (a *Assertions) Truef(value bool, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1444,7 +1528,7 @@ func (a *Assertions) Truef(value bool, msg string, args ...interface{}) { // WithinDuration asserts that the two times are within duration delta of each other. // -// a.WithinDuration(time.Now(), time.Now(), 10*time.Second) +// a.WithinDuration(time.Now(), time.Now(), 10*time.Second) func (a *Assertions) WithinDuration(expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1454,7 +1538,7 @@ func (a *Assertions) WithinDuration(expected time.Time, actual time.Time, delta // WithinDurationf asserts that the two times are within duration delta of each other. // -// a.WithinDurationf(time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted") +// a.WithinDurationf(time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted") func (a *Assertions) WithinDurationf(expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1464,7 +1548,7 @@ func (a *Assertions) WithinDurationf(expected time.Time, actual time.Time, delta // WithinRange asserts that a time is within a time range (inclusive). // -// a.WithinRange(time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second)) +// a.WithinRange(time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second)) func (a *Assertions) WithinRange(actual time.Time, start time.Time, end time.Time, msgAndArgs ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1474,7 +1558,7 @@ func (a *Assertions) WithinRange(actual time.Time, start time.Time, end time.Tim // WithinRangef asserts that a time is within a time range (inclusive). // -// a.WithinRangef(time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), "error message %s", "formatted") +// a.WithinRangef(time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), "error message %s", "formatted") func (a *Assertions) WithinRangef(actual time.Time, start time.Time, end time.Time, msg string, args ...interface{}) { if h, ok := a.t.(tHelper); ok { h.Helper() diff --git a/vendor/github.com/stretchr/testify/suite/doc.go b/vendor/github.com/stretchr/testify/suite/doc.go index f91a245d3f..8d55a3aa89 100644 --- a/vendor/github.com/stretchr/testify/suite/doc.go +++ b/vendor/github.com/stretchr/testify/suite/doc.go @@ -29,37 +29,38 @@ // Suite object has assertion methods. // // A crude example: -// // Basic imports -// import ( -// "testing" -// "github.com/stretchr/testify/assert" -// "github.com/stretchr/testify/suite" -// ) // -// // Define the suite, and absorb the built-in basic suite -// // functionality from testify - including a T() method which -// // returns the current testing context -// type ExampleTestSuite struct { -// suite.Suite -// VariableThatShouldStartAtFive int -// } +// // Basic imports +// import ( +// "testing" +// "github.com/stretchr/testify/assert" +// "github.com/stretchr/testify/suite" +// ) // -// // Make sure that VariableThatShouldStartAtFive is set to five -// // before each test -// func (suite *ExampleTestSuite) SetupTest() { -// suite.VariableThatShouldStartAtFive = 5 -// } +// // Define the suite, and absorb the built-in basic suite +// // functionality from testify - including a T() method which +// // returns the current testing context +// type ExampleTestSuite struct { +// suite.Suite +// VariableThatShouldStartAtFive int +// } // -// // All methods that begin with "Test" are run as tests within a -// // suite. -// func (suite *ExampleTestSuite) TestExample() { -// assert.Equal(suite.T(), 5, suite.VariableThatShouldStartAtFive) -// suite.Equal(5, suite.VariableThatShouldStartAtFive) -// } +// // Make sure that VariableThatShouldStartAtFive is set to five +// // before each test +// func (suite *ExampleTestSuite) SetupTest() { +// suite.VariableThatShouldStartAtFive = 5 +// } // -// // In order for 'go test' to run this suite, we need to create -// // a normal test function and pass our suite to suite.Run -// func TestExampleTestSuite(t *testing.T) { -// suite.Run(t, new(ExampleTestSuite)) -// } +// // All methods that begin with "Test" are run as tests within a +// // suite. +// func (suite *ExampleTestSuite) TestExample() { +// assert.Equal(suite.T(), 5, suite.VariableThatShouldStartAtFive) +// suite.Equal(5, suite.VariableThatShouldStartAtFive) +// } +// +// // In order for 'go test' to run this suite, we need to create +// // a normal test function and pass our suite to suite.Run +// func TestExampleTestSuite(t *testing.T) { +// suite.Run(t, new(ExampleTestSuite)) +// } package suite diff --git a/vendor/github.com/stretchr/testify/suite/interfaces.go b/vendor/github.com/stretchr/testify/suite/interfaces.go index 8b98a8af27..fed037d7f3 100644 --- a/vendor/github.com/stretchr/testify/suite/interfaces.go +++ b/vendor/github.com/stretchr/testify/suite/interfaces.go @@ -7,6 +7,7 @@ import "testing" type TestingSuite interface { T() *testing.T SetT(*testing.T) + SetS(suite TestingSuite) } // SetupAllSuite has a SetupSuite method, which will run before the @@ -51,3 +52,15 @@ type AfterTest interface { type WithStats interface { HandleStats(suiteName string, stats *SuiteInformation) } + +// SetupSubTest has a SetupSubTest method, which will run before each +// subtest in the suite. +type SetupSubTest interface { + SetupSubTest() +} + +// TearDownSubTest has a TearDownSubTest method, which will run after +// each subtest in the suite have been run. +type TearDownSubTest interface { + TearDownSubTest() +} diff --git a/vendor/github.com/stretchr/testify/suite/suite.go b/vendor/github.com/stretchr/testify/suite/suite.go index 895591878b..8b4202d890 100644 --- a/vendor/github.com/stretchr/testify/suite/suite.go +++ b/vendor/github.com/stretchr/testify/suite/suite.go @@ -22,9 +22,13 @@ var matchMethod = flag.String("testify.m", "", "regular expression to select tes // retrieving the current *testing.T context. type Suite struct { *assert.Assertions + mu sync.RWMutex require *require.Assertions t *testing.T + + // Parent suite to have access to the implemented methods of parent struct + s TestingSuite } // T retrieves the current *testing.T context. @@ -43,6 +47,12 @@ func (suite *Suite) SetT(t *testing.T) { suite.require = require.New(t) } +// SetS needs to set the current test suite as parent +// to get access to the parent methods +func (suite *Suite) SetS(s TestingSuite) { + suite.s = s +} + // Require returns a require context for suite. func (suite *Suite) Require() *require.Assertions { suite.mu.Lock() @@ -85,7 +95,18 @@ func failOnPanic(t *testing.T, r interface{}) { // Provides compatibility with go test pkg -run TestSuite/TestName/SubTestName. func (suite *Suite) Run(name string, subtest func()) bool { oldT := suite.T() - defer suite.SetT(oldT) + + if setupSubTest, ok := suite.s.(SetupSubTest); ok { + setupSubTest.SetupSubTest() + } + + defer func() { + suite.SetT(oldT) + if tearDownSubTest, ok := suite.s.(TearDownSubTest); ok { + tearDownSubTest.TearDownSubTest() + } + }() + return oldT.Run(name, func(t *testing.T) { suite.SetT(t) subtest() @@ -98,6 +119,7 @@ func Run(t *testing.T, suite TestingSuite) { defer recoverAndFailOnPanic(t) suite.SetT(t) + suite.SetS(suite) var suiteSetupDone bool diff --git a/vendor/github.com/tklauser/go-sysconf/.cirrus.yml b/vendor/github.com/tklauser/go-sysconf/.cirrus.yml index c7d5293a0e..1b27f19628 100644 --- a/vendor/github.com/tklauser/go-sysconf/.cirrus.yml +++ b/vendor/github.com/tklauser/go-sysconf/.cirrus.yml @@ -1,22 +1,23 @@ env: CIRRUS_CLONE_DEPTH: 1 + GO_VERSION: go1.20 freebsd_12_task: freebsd_instance: image_family: freebsd-12-3 install_script: | - pkg install -y git go - GOBIN=$PWD/bin go install golang.org/dl/go1.17.7@latest - bin/go1.17.7 download - build_script: bin/go1.17.7 build -v ./... - test_script: bin/go1.17.7 test -race ./... + pkg install -y go + GOBIN=$PWD/bin go install golang.org/dl/${GO_VERSION}@latest + bin/${GO_VERSION} download + build_script: bin/${GO_VERSION} build -v ./... + test_script: bin/${GO_VERSION} test -race ./... freebsd_13_task: freebsd_instance: image_family: freebsd-13-0 install_script: | - pkg install -y git go - GOBIN=$PWD/bin go install golang.org/dl/go1.17.7@latest - bin/go1.17.7 download - build_script: bin/go1.17.7 build -v ./... - test_script: bin/go1.17.7 test -race ./... + pkg install -y go + GOBIN=$PWD/bin go install golang.org/dl/${GO_VERSION}@latest + bin/${GO_VERSION} download + build_script: bin/${GO_VERSION} build -v ./... + test_script: bin/${GO_VERSION} test -race ./... diff --git a/vendor/github.com/tklauser/go-sysconf/LICENSE b/vendor/github.com/tklauser/go-sysconf/LICENSE index cf198debc6..73c6b8991e 100644 --- a/vendor/github.com/tklauser/go-sysconf/LICENSE +++ b/vendor/github.com/tklauser/go-sysconf/LICENSE @@ -1,6 +1,6 @@ BSD 3-Clause License -Copyright (c) 2018-2021, Tobias Klauser +Copyright (c) 2018-2022, Tobias Klauser All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/vendor/github.com/tklauser/go-sysconf/sysconf_darwin.go b/vendor/github.com/tklauser/go-sysconf/sysconf_darwin.go index 4a5197b2fc..3f5d83f692 100644 --- a/vendor/github.com/tklauser/go-sysconf/sysconf_darwin.go +++ b/vendor/github.com/tklauser/go-sysconf/sysconf_darwin.go @@ -5,6 +5,10 @@ package sysconf import ( + "strconv" + "strings" + "sync" + "golang.org/x/sys/unix" ) @@ -14,8 +18,14 @@ const ( _SYMLOOP_MAX = _MAXSYMLINKS ) -// sysconf implements sysconf(3) as in the Darwin libc, version 1244.30.3 -// (derived from the FreeBSD libc). +var uname struct { + sync.Once + macOSMajor int +} + +// sysconf implements sysconf(4) as in the Darwin libc (derived from the FreeBSD +// libc), version 1534.81.1. +// See https://github.com/apple-oss-distributions/Libc/tree/Libc-1534.81.1. func sysconf(name int) (int64, error) { switch name { case SC_AIO_LISTIO_MAX: @@ -54,12 +64,16 @@ func sysconf(name int) (int64, error) { return sysctl32("kern.ngroups"), nil case SC_OPEN_MAX, SC_STREAM_MAX: var rlim unix.Rlimit - if err := unix.Getrlimit(unix.RLIMIT_NOFILE, &rlim); err == nil { - if rlim.Cur != unix.RLIM_INFINITY { - return int64(rlim.Cur), nil - } + if err := unix.Getrlimit(unix.RLIMIT_NOFILE, &rlim); err != nil { + return -1, nil } - return -1, nil + if rlim.Cur > unix.RLIM_INFINITY { + return -1, nil + } + if rlim.Cur > _LONG_MAX { + return -1, unix.EOVERFLOW + } + return int64(rlim.Cur), nil case SC_RTSIG_MAX: return -1, nil case SC_SEM_NSEMS_MAX: @@ -126,7 +140,22 @@ func sysconf(name int) (int64, error) { } return _POSIX_SEMAPHORES, nil case SC_SPAWN: - return _POSIX_SPAWN, nil + uname.Once.Do(func() { + var u unix.Utsname + err := unix.Uname(&u) + if err != nil { + return + } + rel := unix.ByteSliceToString(u.Release[:]) + ver := strings.Split(rel, ".") + maj, _ := strconv.Atoi(ver[0]) + uname.macOSMajor = maj + }) + if uname.macOSMajor < 22 { + return -1, nil + } + // macOS 13 (Ventura) and later + return 200112, nil case SC_SPIN_LOCKS: return _POSIX_SPIN_LOCKS, nil case SC_SPORADIC_SERVER: diff --git a/vendor/github.com/tklauser/go-sysconf/zsysconf_defs_darwin.go b/vendor/github.com/tklauser/go-sysconf/zsysconf_defs_darwin.go index 6fa7fde8af..6fadf3db1f 100644 --- a/vendor/github.com/tklauser/go-sysconf/zsysconf_defs_darwin.go +++ b/vendor/github.com/tklauser/go-sysconf/zsysconf_defs_darwin.go @@ -181,7 +181,6 @@ const ( _POSIX_SHARED_MEMORY_OBJECTS = -0x1 _POSIX_SHELL = 0x30db0 _POSIX_SIGQUEUE_MAX = 0x20 - _POSIX_SPAWN = -0x1 _POSIX_SPIN_LOCKS = -0x1 _POSIX_SPORADIC_SERVER = -0x1 _POSIX_SS_REPL_MAX = 0x4 @@ -248,7 +247,8 @@ const ( const ( _CHAR_BIT = 0x8 - _INT_MAX = 0x7fffffff + _INT_MAX = 0x7fffffff + _LONG_MAX = 0x7fffffffffffffff sizeofOffT = 0x8 ) diff --git a/vendor/github.com/tklauser/go-sysconf/zsysconf_values_freebsd_riscv64.go b/vendor/github.com/tklauser/go-sysconf/zsysconf_values_freebsd_riscv64.go new file mode 100644 index 0000000000..b7cff760b1 --- /dev/null +++ b/vendor/github.com/tklauser/go-sysconf/zsysconf_values_freebsd_riscv64.go @@ -0,0 +1,12 @@ +// Code generated by cmd/cgo -godefs; DO NOT EDIT. +// cgo -godefs sysconf_values_freebsd.go + +//go:build freebsd && riscv64 +// +build freebsd,riscv64 + +package sysconf + +const ( + _LONG_MAX = 0x7fffffffffffffff + _SHRT_MAX = 0x7fff +) diff --git a/vendor/github.com/tklauser/numcpus/.cirrus.yml b/vendor/github.com/tklauser/numcpus/.cirrus.yml index 11a39e2143..69c6ced5c7 100644 --- a/vendor/github.com/tklauser/numcpus/.cirrus.yml +++ b/vendor/github.com/tklauser/numcpus/.cirrus.yml @@ -1,12 +1,13 @@ env: CIRRUS_CLONE_DEPTH: 1 + GO_VERSION: go1.20 freebsd_12_task: freebsd_instance: image_family: freebsd-12-3 install_script: | - pkg install -y git go - GOBIN=$PWD/bin go install golang.org/dl/go1.17.6@latest - bin/go1.17.6 download - build_script: bin/go1.17.6 build -v ./... - test_script: bin/go1.17.6 test -race ./... + pkg install -y go + GOBIN=$PWD/bin go install golang.org/dl/${GO_VERSION}@latest + bin/${GO_VERSION} download + build_script: bin/${GO_VERSION} build -buildvcs=false -v ./... + test_script: bin/${GO_VERSION} test -buildvcs=false -race ./... diff --git a/vendor/github.com/yusufpapurcu/wmi/README.md b/vendor/github.com/yusufpapurcu/wmi/README.md index c4a432d6db..426d1a46b4 100644 --- a/vendor/github.com/yusufpapurcu/wmi/README.md +++ b/vendor/github.com/yusufpapurcu/wmi/README.md @@ -4,10 +4,3 @@ wmi Package wmi provides a WQL interface to Windows WMI. Note: It interfaces with WMI on the local machine, therefore it only runs on Windows. - ---- - -NOTE: This project is no longer being actively maintained. If you would like -to become its new owner, please contact tlimoncelli at stack over flow dot com. - ---- diff --git a/vendor/github.com/yusufpapurcu/wmi/swbemservices.go b/vendor/github.com/yusufpapurcu/wmi/swbemservices.go index 3ff8756303..a250c846d5 100644 --- a/vendor/github.com/yusufpapurcu/wmi/swbemservices.go +++ b/vendor/github.com/yusufpapurcu/wmi/swbemservices.go @@ -1,3 +1,4 @@ +//go:build windows // +build windows package wmi diff --git a/vendor/github.com/yusufpapurcu/wmi/wmi.go b/vendor/github.com/yusufpapurcu/wmi/wmi.go index b4bb4f0901..26c3581c97 100644 --- a/vendor/github.com/yusufpapurcu/wmi/wmi.go +++ b/vendor/github.com/yusufpapurcu/wmi/wmi.go @@ -1,3 +1,4 @@ +//go:build windows // +build windows /* @@ -20,7 +21,6 @@ Example code to print names of running processes: println(i, v.Name) } } - */ package wmi @@ -338,11 +338,6 @@ func (c *Client) loadEntity(dst interface{}, src *ole.IDispatch) (errFieldMismat f := v.Field(i) of := f isPtr := f.Kind() == reflect.Ptr - if isPtr { - ptr := reflect.New(f.Type().Elem()) - f.Set(ptr) - f = f.Elem() - } n := v.Type().Field(i).Name if n[0] < 'A' || n[0] > 'Z' { continue @@ -367,6 +362,12 @@ func (c *Client) loadEntity(dst interface{}, src *ole.IDispatch) (errFieldMismat } defer prop.Clear() + if isPtr && !(c.PtrNil && prop.VT == 0x1) { + ptr := reflect.New(f.Type().Elem()) + f.Set(ptr) + f = f.Elem() + } + if prop.VT == 0x1 { //VT_NULL continue } diff --git a/vendor/golang.org/x/sys/cpu/endian_little.go b/vendor/golang.org/x/sys/cpu/endian_little.go index fe545966b6..55db853efb 100644 --- a/vendor/golang.org/x/sys/cpu/endian_little.go +++ b/vendor/golang.org/x/sys/cpu/endian_little.go @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build 386 || amd64 || amd64p32 || alpha || arm || arm64 || loong64 || mipsle || mips64le || mips64p32le || nios2 || ppc64le || riscv || riscv64 || sh -// +build 386 amd64 amd64p32 alpha arm arm64 loong64 mipsle mips64le mips64p32le nios2 ppc64le riscv riscv64 sh +//go:build 386 || amd64 || amd64p32 || alpha || arm || arm64 || loong64 || mipsle || mips64le || mips64p32le || nios2 || ppc64le || riscv || riscv64 || sh || wasm +// +build 386 amd64 amd64p32 alpha arm arm64 loong64 mipsle mips64le mips64p32le nios2 ppc64le riscv riscv64 sh wasm package cpu diff --git a/vendor/golang.org/x/sys/unix/ioctl_signed.go b/vendor/golang.org/x/sys/unix/ioctl_signed.go new file mode 100644 index 0000000000..7def9580e6 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/ioctl_signed.go @@ -0,0 +1,70 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build aix || solaris +// +build aix solaris + +package unix + +import ( + "unsafe" +) + +// ioctl itself should not be exposed directly, but additional get/set +// functions for specific types are permissible. + +// IoctlSetInt performs an ioctl operation which sets an integer value +// on fd, using the specified request number. +func IoctlSetInt(fd int, req int, value int) error { + return ioctl(fd, req, uintptr(value)) +} + +// IoctlSetPointerInt performs an ioctl operation which sets an +// integer value on fd, using the specified request number. The ioctl +// argument is called with a pointer to the integer value, rather than +// passing the integer value directly. +func IoctlSetPointerInt(fd int, req int, value int) error { + v := int32(value) + return ioctlPtr(fd, req, unsafe.Pointer(&v)) +} + +// IoctlSetWinsize performs an ioctl on fd with a *Winsize argument. +// +// To change fd's window size, the req argument should be TIOCSWINSZ. +func IoctlSetWinsize(fd int, req int, value *Winsize) error { + // TODO: if we get the chance, remove the req parameter and + // hardcode TIOCSWINSZ. + return ioctlPtr(fd, req, unsafe.Pointer(value)) +} + +// IoctlSetTermios performs an ioctl on fd with a *Termios. +// +// The req value will usually be TCSETA or TIOCSETA. +func IoctlSetTermios(fd int, req int, value *Termios) error { + // TODO: if we get the chance, remove the req parameter. + return ioctlPtr(fd, req, unsafe.Pointer(value)) +} + +// IoctlGetInt performs an ioctl operation which gets an integer value +// from fd, using the specified request number. +// +// A few ioctl requests use the return value as an output parameter; +// for those, IoctlRetInt should be used instead of this function. +func IoctlGetInt(fd int, req int) (int, error) { + var value int + err := ioctlPtr(fd, req, unsafe.Pointer(&value)) + return value, err +} + +func IoctlGetWinsize(fd int, req int) (*Winsize, error) { + var value Winsize + err := ioctlPtr(fd, req, unsafe.Pointer(&value)) + return &value, err +} + +func IoctlGetTermios(fd int, req int) (*Termios, error) { + var value Termios + err := ioctlPtr(fd, req, unsafe.Pointer(&value)) + return &value, err +} diff --git a/vendor/golang.org/x/sys/unix/ioctl.go b/vendor/golang.org/x/sys/unix/ioctl_unsigned.go similarity index 92% rename from vendor/golang.org/x/sys/unix/ioctl.go rename to vendor/golang.org/x/sys/unix/ioctl_unsigned.go index 7ce8dd406f..649913d1ea 100644 --- a/vendor/golang.org/x/sys/unix/ioctl.go +++ b/vendor/golang.org/x/sys/unix/ioctl_unsigned.go @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build aix || darwin || dragonfly || freebsd || hurd || linux || netbsd || openbsd || solaris -// +build aix darwin dragonfly freebsd hurd linux netbsd openbsd solaris +//go:build darwin || dragonfly || freebsd || hurd || linux || netbsd || openbsd +// +build darwin dragonfly freebsd hurd linux netbsd openbsd package unix diff --git a/vendor/golang.org/x/sys/unix/ioctl_zos.go b/vendor/golang.org/x/sys/unix/ioctl_zos.go index 6532f09af2..cdc21bf76d 100644 --- a/vendor/golang.org/x/sys/unix/ioctl_zos.go +++ b/vendor/golang.org/x/sys/unix/ioctl_zos.go @@ -17,14 +17,14 @@ import ( // IoctlSetInt performs an ioctl operation which sets an integer value // on fd, using the specified request number. -func IoctlSetInt(fd int, req uint, value int) error { +func IoctlSetInt(fd int, req int, value int) error { return ioctl(fd, req, uintptr(value)) } // IoctlSetWinsize performs an ioctl on fd with a *Winsize argument. // // To change fd's window size, the req argument should be TIOCSWINSZ. -func IoctlSetWinsize(fd int, req uint, value *Winsize) error { +func IoctlSetWinsize(fd int, req int, value *Winsize) error { // TODO: if we get the chance, remove the req parameter and // hardcode TIOCSWINSZ. return ioctlPtr(fd, req, unsafe.Pointer(value)) @@ -33,7 +33,7 @@ func IoctlSetWinsize(fd int, req uint, value *Winsize) error { // IoctlSetTermios performs an ioctl on fd with a *Termios. // // The req value is expected to be TCSETS, TCSETSW, or TCSETSF -func IoctlSetTermios(fd int, req uint, value *Termios) error { +func IoctlSetTermios(fd int, req int, value *Termios) error { if (req != TCSETS) && (req != TCSETSW) && (req != TCSETSF) { return ENOSYS } @@ -47,13 +47,13 @@ func IoctlSetTermios(fd int, req uint, value *Termios) error { // // A few ioctl requests use the return value as an output parameter; // for those, IoctlRetInt should be used instead of this function. -func IoctlGetInt(fd int, req uint) (int, error) { +func IoctlGetInt(fd int, req int) (int, error) { var value int err := ioctlPtr(fd, req, unsafe.Pointer(&value)) return value, err } -func IoctlGetWinsize(fd int, req uint) (*Winsize, error) { +func IoctlGetWinsize(fd int, req int) (*Winsize, error) { var value Winsize err := ioctlPtr(fd, req, unsafe.Pointer(&value)) return &value, err @@ -62,7 +62,7 @@ func IoctlGetWinsize(fd int, req uint) (*Winsize, error) { // IoctlGetTermios performs an ioctl on fd with a *Termios. // // The req value is expected to be TCGETS -func IoctlGetTermios(fd int, req uint) (*Termios, error) { +func IoctlGetTermios(fd int, req int) (*Termios, error) { var value Termios if req != TCGETS { return &value, ENOSYS diff --git a/vendor/golang.org/x/sys/unix/mkall.sh b/vendor/golang.org/x/sys/unix/mkall.sh index 8e3947c368..e6f31d374d 100644 --- a/vendor/golang.org/x/sys/unix/mkall.sh +++ b/vendor/golang.org/x/sys/unix/mkall.sh @@ -50,7 +50,7 @@ if [[ "$GOOS" = "linux" ]]; then # Use the Docker-based build system # Files generated through docker (use $cmd so you can Ctl-C the build or run) $cmd docker build --tag generate:$GOOS $GOOS - $cmd docker run --interactive --tty --volume $(cd -- "$(dirname -- "$0")/.." && /bin/pwd):/build generate:$GOOS + $cmd docker run --interactive --tty --volume $(cd -- "$(dirname -- "$0")/.." && pwd):/build generate:$GOOS exit fi diff --git a/vendor/golang.org/x/sys/unix/mkerrors.sh b/vendor/golang.org/x/sys/unix/mkerrors.sh index 7456d9ddde..8f775fafa6 100644 --- a/vendor/golang.org/x/sys/unix/mkerrors.sh +++ b/vendor/golang.org/x/sys/unix/mkerrors.sh @@ -66,6 +66,7 @@ includes_Darwin=' #include #include #include +#include #include #include #include @@ -203,6 +204,7 @@ struct ltchars { #include #include #include +#include #include #include #include @@ -517,10 +519,11 @@ ccflags="$@" $2 ~ /^LOCK_(SH|EX|NB|UN)$/ || $2 ~ /^LO_(KEY|NAME)_SIZE$/ || $2 ~ /^LOOP_(CLR|CTL|GET|SET)_/ || - $2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|TCP|MCAST|EVFILT|NOTE|SHUT|PROT|MAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR|LOCAL|TCPOPT)_/ || + $2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|TCP|MCAST|EVFILT|NOTE|SHUT|PROT|MAP|MREMAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR|LOCAL|TCPOPT|UDP)_/ || $2 ~ /^NFC_(GENL|PROTO|COMM|RF|SE|DIRECTION|LLCP|SOCKPROTO)_/ || $2 ~ /^NFC_.*_(MAX)?SIZE$/ || $2 ~ /^RAW_PAYLOAD_/ || + $2 ~ /^[US]F_/ || $2 ~ /^TP_STATUS_/ || $2 ~ /^FALLOC_/ || $2 ~ /^ICMPV?6?_(FILTER|SEC)/ || @@ -621,7 +624,7 @@ ccflags="$@" $2 ~ /^MEM/ || $2 ~ /^WG/ || $2 ~ /^FIB_RULE_/ || - $2 ~ /^BLK[A-Z]*(GET$|SET$|BUF$|PART$|SIZE)/ {printf("\t%s = C.%s\n", $2, $2)} + $2 ~ /^BLK[A-Z]*(GET$|SET$|BUF$|PART$|SIZE|IOMIN$|IOOPT$|ALIGNOFF$|DISCARD|ROTATIONAL$|ZEROOUT$|GETDISKSEQ$)/ {printf("\t%s = C.%s\n", $2, $2)} $2 ~ /^__WCOREFLAG$/ {next} $2 ~ /^__W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", substr($2,3), $2)} @@ -738,7 +741,8 @@ main(void) e = errors[i].num; if(i > 0 && errors[i-1].num == e) continue; - strcpy(buf, strerror(e)); + strncpy(buf, strerror(e), sizeof(buf) - 1); + buf[sizeof(buf) - 1] = '\0'; // lowercase first letter: Bad -> bad, but STREAM -> STREAM. if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z) buf[0] += a - A; @@ -757,7 +761,8 @@ main(void) e = signals[i].num; if(i > 0 && signals[i-1].num == e) continue; - strcpy(buf, strsignal(e)); + strncpy(buf, strsignal(e), sizeof(buf) - 1); + buf[sizeof(buf) - 1] = '\0'; // lowercase first letter: Bad -> bad, but STREAM -> STREAM. if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z) buf[0] += a - A; diff --git a/vendor/golang.org/x/sys/unix/mmap_nomremap.go b/vendor/golang.org/x/sys/unix/mmap_nomremap.go new file mode 100644 index 0000000000..ca0513632e --- /dev/null +++ b/vendor/golang.org/x/sys/unix/mmap_nomremap.go @@ -0,0 +1,14 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build aix || darwin || dragonfly || freebsd || openbsd || solaris +// +build aix darwin dragonfly freebsd openbsd solaris + +package unix + +var mapper = &mmapper{ + active: make(map[*byte][]byte), + mmap: mmap, + munmap: munmap, +} diff --git a/vendor/golang.org/x/sys/unix/mremap.go b/vendor/golang.org/x/sys/unix/mremap.go new file mode 100644 index 0000000000..fa93d0aa90 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/mremap.go @@ -0,0 +1,53 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build linux || netbsd +// +build linux netbsd + +package unix + +import "unsafe" + +type mremapMmapper struct { + mmapper + mremap func(oldaddr uintptr, oldlength uintptr, newlength uintptr, flags int, newaddr uintptr) (xaddr uintptr, err error) +} + +var mapper = &mremapMmapper{ + mmapper: mmapper{ + active: make(map[*byte][]byte), + mmap: mmap, + munmap: munmap, + }, + mremap: mremap, +} + +func (m *mremapMmapper) Mremap(oldData []byte, newLength int, flags int) (data []byte, err error) { + if newLength <= 0 || len(oldData) == 0 || len(oldData) != cap(oldData) || flags&mremapFixed != 0 { + return nil, EINVAL + } + + pOld := &oldData[cap(oldData)-1] + m.Lock() + defer m.Unlock() + bOld := m.active[pOld] + if bOld == nil || &bOld[0] != &oldData[0] { + return nil, EINVAL + } + newAddr, errno := m.mremap(uintptr(unsafe.Pointer(&bOld[0])), uintptr(len(bOld)), uintptr(newLength), flags, 0) + if errno != nil { + return nil, errno + } + bNew := unsafe.Slice((*byte)(unsafe.Pointer(newAddr)), newLength) + pNew := &bNew[cap(bNew)-1] + if flags&mremapDontunmap == 0 { + delete(m.active, pOld) + } + m.active[pNew] = bNew + return bNew, nil +} + +func Mremap(oldData []byte, newLength int, flags int) (data []byte, err error) { + return mapper.Mremap(oldData, newLength, flags) +} diff --git a/vendor/golang.org/x/sys/unix/syscall_aix.go b/vendor/golang.org/x/sys/unix/syscall_aix.go index d9f5544ccf..9a6e5acacb 100644 --- a/vendor/golang.org/x/sys/unix/syscall_aix.go +++ b/vendor/golang.org/x/sys/unix/syscall_aix.go @@ -408,8 +408,8 @@ func (w WaitStatus) CoreDump() bool { return w&0x80 == 0x80 } func (w WaitStatus) TrapCause() int { return -1 } -//sys ioctl(fd int, req uint, arg uintptr) (err error) -//sys ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) = ioctl +//sys ioctl(fd int, req int, arg uintptr) (err error) +//sys ioctlPtr(fd int, req int, arg unsafe.Pointer) (err error) = ioctl // fcntl must never be called with cmd=F_DUP2FD because it doesn't work on AIX // There is no way to create a custom fcntl and to keep //sys fcntl easily, @@ -535,21 +535,6 @@ func Fsync(fd int) error { //sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) = nsendmsg //sys munmap(addr uintptr, length uintptr) (err error) - -var mapper = &mmapper{ - active: make(map[*byte][]byte), - mmap: mmap, - munmap: munmap, -} - -func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) { - return mapper.Mmap(fd, offset, length, prot, flags) -} - -func Munmap(b []byte) (err error) { - return mapper.Munmap(b) -} - //sys Madvise(b []byte, advice int) (err error) //sys Mprotect(b []byte, prot int) (err error) //sys Mlock(b []byte) (err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_aix_ppc.go b/vendor/golang.org/x/sys/unix/syscall_aix_ppc.go index e92a0be163..f2871fa953 100644 --- a/vendor/golang.org/x/sys/unix/syscall_aix_ppc.go +++ b/vendor/golang.org/x/sys/unix/syscall_aix_ppc.go @@ -8,7 +8,6 @@ package unix //sysnb Getrlimit(resource int, rlim *Rlimit) (err error) = getrlimit64 -//sysnb Setrlimit(resource int, rlim *Rlimit) (err error) = setrlimit64 //sys Seek(fd int, offset int64, whence int) (off int64, err error) = lseek64 //sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_aix_ppc64.go b/vendor/golang.org/x/sys/unix/syscall_aix_ppc64.go index 16eed17098..75718ec0f1 100644 --- a/vendor/golang.org/x/sys/unix/syscall_aix_ppc64.go +++ b/vendor/golang.org/x/sys/unix/syscall_aix_ppc64.go @@ -8,7 +8,6 @@ package unix //sysnb Getrlimit(resource int, rlim *Rlimit) (err error) -//sysnb Setrlimit(resource int, rlim *Rlimit) (err error) //sys Seek(fd int, offset int64, whence int) (off int64, err error) = lseek //sys mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) = mmap64 diff --git a/vendor/golang.org/x/sys/unix/syscall_bsd.go b/vendor/golang.org/x/sys/unix/syscall_bsd.go index 7705c3270b..4217de518b 100644 --- a/vendor/golang.org/x/sys/unix/syscall_bsd.go +++ b/vendor/golang.org/x/sys/unix/syscall_bsd.go @@ -601,20 +601,6 @@ func Poll(fds []PollFd, timeout int) (n int, err error) { // Gethostuuid(uuid *byte, timeout *Timespec) (err error) // Ptrace(req int, pid int, addr uintptr, data int) (ret uintptr, err error) -var mapper = &mmapper{ - active: make(map[*byte][]byte), - mmap: mmap, - munmap: munmap, -} - -func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) { - return mapper.Mmap(fd, offset, length, prot, flags) -} - -func Munmap(b []byte) (err error) { - return mapper.Munmap(b) -} - //sys Madvise(b []byte, behav int) (err error) //sys Mlock(b []byte) (err error) //sys Mlockall(flags int) (err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin.go b/vendor/golang.org/x/sys/unix/syscall_darwin.go index 7064d6ebab..135cc3cd75 100644 --- a/vendor/golang.org/x/sys/unix/syscall_darwin.go +++ b/vendor/golang.org/x/sys/unix/syscall_darwin.go @@ -510,30 +510,36 @@ func SysctlKinfoProcSlice(name string, args ...int) ([]KinfoProc, error) { return nil, err } - // Find size. - n := uintptr(0) - if err := sysctl(mib, nil, &n, nil, 0); err != nil { - return nil, err - } - if n == 0 { - return nil, nil - } - if n%SizeofKinfoProc != 0 { - return nil, fmt.Errorf("sysctl() returned a size of %d, which is not a multiple of %d", n, SizeofKinfoProc) - } + for { + // Find size. + n := uintptr(0) + if err := sysctl(mib, nil, &n, nil, 0); err != nil { + return nil, err + } + if n == 0 { + return nil, nil + } + if n%SizeofKinfoProc != 0 { + return nil, fmt.Errorf("sysctl() returned a size of %d, which is not a multiple of %d", n, SizeofKinfoProc) + } - // Read into buffer of that size. - buf := make([]KinfoProc, n/SizeofKinfoProc) - if err := sysctl(mib, (*byte)(unsafe.Pointer(&buf[0])), &n, nil, 0); err != nil { - return nil, err - } - if n%SizeofKinfoProc != 0 { - return nil, fmt.Errorf("sysctl() returned a size of %d, which is not a multiple of %d", n, SizeofKinfoProc) - } + // Read into buffer of that size. + buf := make([]KinfoProc, n/SizeofKinfoProc) + if err := sysctl(mib, (*byte)(unsafe.Pointer(&buf[0])), &n, nil, 0); err != nil { + if err == ENOMEM { + // Process table grew. Try again. + continue + } + return nil, err + } + if n%SizeofKinfoProc != 0 { + return nil, fmt.Errorf("sysctl() returned a size of %d, which is not a multiple of %d", n, SizeofKinfoProc) + } - // The actual call may return less than the original reported required - // size so ensure we deal with that. - return buf[:n/SizeofKinfoProc], nil + // The actual call may return less than the original reported required + // size so ensure we deal with that. + return buf[:n/SizeofKinfoProc], nil + } } //sys sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) @@ -613,6 +619,7 @@ func SysctlKinfoProcSlice(name string, args ...int) ([]KinfoProc, error) { //sys Rmdir(path string) (err error) //sys Seek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_LSEEK //sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) +//sys Setattrlist(path string, attrlist *Attrlist, attrBuf []byte, options int) (err error) //sys Setegid(egid int) (err error) //sysnb Seteuid(euid int) (err error) //sysnb Setgid(gid int) (err error) @@ -622,7 +629,6 @@ func SysctlKinfoProcSlice(name string, args ...int) ([]KinfoProc, error) { //sys Setprivexec(flag int) (err error) //sysnb Setregid(rgid int, egid int) (err error) //sysnb Setreuid(ruid int, euid int) (err error) -//sysnb Setrlimit(which int, lim *Rlimit) (err error) //sysnb Setsid() (pid int, err error) //sysnb Settimeofday(tp *Timeval) (err error) //sysnb Setuid(uid int) (err error) @@ -676,7 +682,6 @@ func SysctlKinfoProcSlice(name string, args ...int) ([]KinfoProc, error) { // Kqueue_from_portset_np // Kqueue_portset // Getattrlist -// Setattrlist // Getdirentriesattr // Searchfs // Delete diff --git a/vendor/golang.org/x/sys/unix/syscall_dragonfly.go b/vendor/golang.org/x/sys/unix/syscall_dragonfly.go index 221efc26bc..d4ce988e72 100644 --- a/vendor/golang.org/x/sys/unix/syscall_dragonfly.go +++ b/vendor/golang.org/x/sys/unix/syscall_dragonfly.go @@ -326,7 +326,6 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e //sysnb Setreuid(ruid int, euid int) (err error) //sysnb Setresgid(rgid int, egid int, sgid int) (err error) //sysnb Setresuid(ruid int, euid int, suid int) (err error) -//sysnb Setrlimit(which int, lim *Rlimit) (err error) //sysnb Setsid() (pid int, err error) //sysnb Settimeofday(tp *Timeval) (err error) //sysnb Setuid(uid int) (err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_freebsd.go b/vendor/golang.org/x/sys/unix/syscall_freebsd.go index 5bdde03e4a..afb10106f6 100644 --- a/vendor/golang.org/x/sys/unix/syscall_freebsd.go +++ b/vendor/golang.org/x/sys/unix/syscall_freebsd.go @@ -433,7 +433,6 @@ func Dup3(oldfd, newfd, flags int) error { //sysnb Setreuid(ruid int, euid int) (err error) //sysnb Setresgid(rgid int, egid int, sgid int) (err error) //sysnb Setresuid(ruid int, euid int, suid int) (err error) -//sysnb Setrlimit(which int, lim *Rlimit) (err error) //sysnb Setsid() (pid int, err error) //sysnb Settimeofday(tp *Timeval) (err error) //sysnb Setuid(uid int) (err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go index 9735331530..a730878e49 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux.go @@ -1699,12 +1699,23 @@ func PtracePokeUser(pid int, addr uintptr, data []byte) (count int, err error) { return ptracePoke(PTRACE_POKEUSR, PTRACE_PEEKUSR, pid, addr, data) } +// elfNT_PRSTATUS is a copy of the debug/elf.NT_PRSTATUS constant so +// x/sys/unix doesn't need to depend on debug/elf and thus +// compress/zlib, debug/dwarf, and other packages. +const elfNT_PRSTATUS = 1 + func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) { - return ptracePtr(PTRACE_GETREGS, pid, 0, unsafe.Pointer(regsout)) + var iov Iovec + iov.Base = (*byte)(unsafe.Pointer(regsout)) + iov.SetLen(int(unsafe.Sizeof(*regsout))) + return ptracePtr(PTRACE_GETREGSET, pid, uintptr(elfNT_PRSTATUS), unsafe.Pointer(&iov)) } func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) { - return ptracePtr(PTRACE_SETREGS, pid, 0, unsafe.Pointer(regs)) + var iov Iovec + iov.Base = (*byte)(unsafe.Pointer(regs)) + iov.SetLen(int(unsafe.Sizeof(*regs))) + return ptracePtr(PTRACE_SETREGSET, pid, uintptr(elfNT_PRSTATUS), unsafe.Pointer(&iov)) } func PtraceSetOptions(pid int, options int) (err error) { @@ -1873,9 +1884,8 @@ func Getpgrp() (pid int) { //sys OpenTree(dfd int, fileName string, flags uint) (r int, err error) //sys PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error) //sys PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT -//sysnb Prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT64 //sys Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error) -//sys Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) = SYS_PSELECT6 +//sys pselect6(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *sigset_argpack) (n int, err error) //sys read(fd int, p []byte) (n int, err error) //sys Removexattr(path string, attr string) (err error) //sys Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) @@ -1887,6 +1897,15 @@ func Getpgrp() (pid int) { //sysnb Settimeofday(tv *Timeval) (err error) //sys Setns(fd int, nstype int) (err error) +//go:linkname syscall_prlimit syscall.prlimit +func syscall_prlimit(pid, resource int, newlimit, old *syscall.Rlimit) error + +func Prlimit(pid, resource int, newlimit, old *Rlimit) error { + // Just call the syscall version, because as of Go 1.21 + // it will affect starting a new process. + return syscall_prlimit(pid, resource, (*syscall.Rlimit)(newlimit), (*syscall.Rlimit)(old)) +} + // PrctlRetInt performs a prctl operation specified by option and further // optional arguments arg2 through arg5 depending on option. It returns a // non-negative integer that is returned by the prctl syscall. @@ -2105,21 +2124,7 @@ func writevRacedetect(iovecs []Iovec, n int) { // mmap varies by architecture; see syscall_linux_*.go. //sys munmap(addr uintptr, length uintptr) (err error) - -var mapper = &mmapper{ - active: make(map[*byte][]byte), - mmap: mmap, - munmap: munmap, -} - -func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) { - return mapper.Mmap(fd, offset, length, prot, flags) -} - -func Munmap(b []byte) (err error) { - return mapper.Munmap(b) -} - +//sys mremap(oldaddr uintptr, oldlength uintptr, newlength uintptr, flags int, newaddr uintptr) (xaddr uintptr, err error) //sys Madvise(b []byte, advice int) (err error) //sys Mprotect(b []byte, prot int) (err error) //sys Mlock(b []byte) (err error) @@ -2128,6 +2133,12 @@ func Munmap(b []byte) (err error) { //sys Munlock(b []byte) (err error) //sys Munlockall() (err error) +const ( + mremapFixed = MREMAP_FIXED + mremapDontunmap = MREMAP_DONTUNMAP + mremapMaymove = MREMAP_MAYMOVE +) + // Vmsplice splices user pages from a slice of Iovecs into a pipe specified by fd, // using the specified flags. func Vmsplice(fd int, iovs []Iovec, flags int) (int, error) { @@ -2412,6 +2423,54 @@ func PthreadSigmask(how int, set, oldset *Sigset_t) error { return rtSigprocmask(how, set, oldset, _C__NSIG/8) } +//sysnb getresuid(ruid *_C_int, euid *_C_int, suid *_C_int) +//sysnb getresgid(rgid *_C_int, egid *_C_int, sgid *_C_int) + +func Getresuid() (ruid, euid, suid int) { + var r, e, s _C_int + getresuid(&r, &e, &s) + return int(r), int(e), int(s) +} + +func Getresgid() (rgid, egid, sgid int) { + var r, e, s _C_int + getresgid(&r, &e, &s) + return int(r), int(e), int(s) +} + +// Pselect is a wrapper around the Linux pselect6 system call. +// This version does not modify the timeout argument. +func Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { + // Per https://man7.org/linux/man-pages/man2/select.2.html#NOTES, + // The Linux pselect6() system call modifies its timeout argument. + // [Not modifying the argument] is the behavior required by POSIX.1-2001. + var mutableTimeout *Timespec + if timeout != nil { + mutableTimeout = new(Timespec) + *mutableTimeout = *timeout + } + + // The final argument of the pselect6() system call is not a + // sigset_t * pointer, but is instead a structure + var kernelMask *sigset_argpack + if sigmask != nil { + wordBits := 32 << (^uintptr(0) >> 63) // see math.intSize + + // A sigset stores one bit per signal, + // offset by 1 (because signal 0 does not exist). + // So the number of words needed is ⌈__C_NSIG - 1 / wordBits⌉. + sigsetWords := (_C__NSIG - 1 + wordBits - 1) / (wordBits) + + sigsetBytes := uintptr(sigsetWords * (wordBits / 8)) + kernelMask = &sigset_argpack{ + ss: sigmask, + ssLen: sigsetBytes, + } + } + + return pselect6(nfd, r, w, e, mutableTimeout, kernelMask) +} + /* * Unimplemented */ @@ -2453,7 +2512,6 @@ func PthreadSigmask(how int, set, oldset *Sigset_t) error { // MqTimedreceive // MqTimedsend // MqUnlink -// Mremap // Msgctl // Msgget // Msgrcv diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_386.go b/vendor/golang.org/x/sys/unix/syscall_linux_386.go index ff5b5899d6..c7d9945ea1 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_386.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_386.go @@ -97,33 +97,6 @@ func Getrlimit(resource int, rlim *Rlimit) (err error) { return } -//sysnb setrlimit(resource int, rlim *rlimit32) (err error) = SYS_SETRLIMIT - -func Setrlimit(resource int, rlim *Rlimit) (err error) { - err = Prlimit(0, resource, rlim, nil) - if err != ENOSYS { - return err - } - - rl := rlimit32{} - if rlim.Cur == rlimInf64 { - rl.Cur = rlimInf32 - } else if rlim.Cur < uint64(rlimInf32) { - rl.Cur = uint32(rlim.Cur) - } else { - return EINVAL - } - if rlim.Max == rlimInf64 { - rl.Max = rlimInf32 - } else if rlim.Max < uint64(rlimInf32) { - rl.Max = uint32(rlim.Max) - } else { - return EINVAL - } - - return setrlimit(resource, &rl) -} - func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { newoffset, errno := seek(fd, offset, whence) if errno != 0 { diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go b/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go index 9b27035329..70601ce369 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go @@ -40,13 +40,12 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err if timeout != nil { ts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000} } - return Pselect(nfd, r, w, e, ts, nil) + return pselect6(nfd, r, w, e, ts, nil) } //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) //sys setfsgid(gid int) (prev int, err error) //sys setfsuid(uid int) (prev int, err error) -//sysnb Setrlimit(resource int, rlim *Rlimit) (err error) //sys Shutdown(fd int, how int) (err error) //sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_arm.go b/vendor/golang.org/x/sys/unix/syscall_linux_arm.go index 856ad1d635..da2986415a 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_arm.go @@ -171,33 +171,6 @@ func Getrlimit(resource int, rlim *Rlimit) (err error) { return } -//sysnb setrlimit(resource int, rlim *rlimit32) (err error) = SYS_SETRLIMIT - -func Setrlimit(resource int, rlim *Rlimit) (err error) { - err = Prlimit(0, resource, rlim, nil) - if err != ENOSYS { - return err - } - - rl := rlimit32{} - if rlim.Cur == rlimInf64 { - rl.Cur = rlimInf32 - } else if rlim.Cur < uint64(rlimInf32) { - rl.Cur = uint32(rlim.Cur) - } else { - return EINVAL - } - if rlim.Max == rlimInf64 { - rl.Max = rlimInf32 - } else if rlim.Max < uint64(rlimInf32) { - rl.Max = uint32(rlim.Max) - } else { - return EINVAL - } - - return setrlimit(resource, &rl) -} - func (r *PtraceRegs) PC() uint64 { return uint64(r.Uregs[15]) } func (r *PtraceRegs) SetPC(pc uint64) { r.Uregs[15] = uint32(pc) } diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go b/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go index 6422704bc5..f5266689af 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go @@ -33,13 +33,12 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err if timeout != nil { ts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000} } - return Pselect(nfd, r, w, e, ts, nil) + return pselect6(nfd, r, w, e, ts, nil) } //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) //sys setfsgid(gid int) (prev int, err error) //sys setfsuid(uid int) (prev int, err error) -//sysnb setrlimit(resource int, rlim *Rlimit) (err error) //sys Shutdown(fd int, how int) (err error) //sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) @@ -143,15 +142,6 @@ func Getrlimit(resource int, rlim *Rlimit) error { return getrlimit(resource, rlim) } -// Setrlimit prefers the prlimit64 system call. See issue 38604. -func Setrlimit(resource int, rlim *Rlimit) error { - err := Prlimit(0, resource, rlim, nil) - if err != ENOSYS { - return err - } - return setrlimit(resource, rlim) -} - func (r *PtraceRegs) PC() uint64 { return r.Pc } func (r *PtraceRegs) SetPC(pc uint64) { r.Pc = pc } diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_loong64.go b/vendor/golang.org/x/sys/unix/syscall_linux_loong64.go index 59dab510e9..f6ab02ec15 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_loong64.go @@ -28,7 +28,7 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err if timeout != nil { ts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000} } - return Pselect(nfd, r, w, e, ts, nil) + return pselect6(nfd, r, w, e, ts, nil) } //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) @@ -126,11 +126,6 @@ func Getrlimit(resource int, rlim *Rlimit) (err error) { return } -func Setrlimit(resource int, rlim *Rlimit) (err error) { - err = Prlimit(0, resource, rlim, nil) - return -} - func futimesat(dirfd int, path string, tv *[2]Timeval) (err error) { if tv == nil { return utimensat(dirfd, path, nil, 0) diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go b/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go index bfef09a39e..93fe59d25d 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go @@ -31,13 +31,12 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err if timeout != nil { ts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000} } - return Pselect(nfd, r, w, e, ts, nil) + return pselect6(nfd, r, w, e, ts, nil) } //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) //sys setfsgid(gid int) (prev int, err error) //sys setfsuid(uid int) (prev int, err error) -//sysnb Setrlimit(resource int, rlim *Rlimit) (err error) //sys Shutdown(fd int, how int) (err error) //sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) //sys Statfs(path string, buf *Statfs_t) (err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go b/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go index ab30250966..aae7f0ffd3 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go @@ -151,33 +151,6 @@ func Getrlimit(resource int, rlim *Rlimit) (err error) { return } -//sysnb setrlimit(resource int, rlim *rlimit32) (err error) = SYS_SETRLIMIT - -func Setrlimit(resource int, rlim *Rlimit) (err error) { - err = Prlimit(0, resource, rlim, nil) - if err != ENOSYS { - return err - } - - rl := rlimit32{} - if rlim.Cur == rlimInf64 { - rl.Cur = rlimInf32 - } else if rlim.Cur < uint64(rlimInf32) { - rl.Cur = uint32(rlim.Cur) - } else { - return EINVAL - } - if rlim.Max == rlimInf64 { - rl.Max = rlimInf32 - } else if rlim.Max < uint64(rlimInf32) { - rl.Max = uint32(rlim.Max) - } else { - return EINVAL - } - - return setrlimit(resource, &rl) -} - func (r *PtraceRegs) PC() uint64 { return r.Epc } func (r *PtraceRegs) SetPC(pc uint64) { r.Epc = pc } diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_ppc.go b/vendor/golang.org/x/sys/unix/syscall_linux_ppc.go index eac1cf1acc..66eff19a32 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_ppc.go @@ -159,33 +159,6 @@ func Getrlimit(resource int, rlim *Rlimit) (err error) { return } -//sysnb setrlimit(resource int, rlim *rlimit32) (err error) = SYS_SETRLIMIT - -func Setrlimit(resource int, rlim *Rlimit) (err error) { - err = Prlimit(0, resource, rlim, nil) - if err != ENOSYS { - return err - } - - rl := rlimit32{} - if rlim.Cur == rlimInf64 { - rl.Cur = rlimInf32 - } else if rlim.Cur < uint64(rlimInf32) { - rl.Cur = uint32(rlim.Cur) - } else { - return EINVAL - } - if rlim.Max == rlimInf64 { - rl.Max = rlimInf32 - } else if rlim.Max < uint64(rlimInf32) { - rl.Max = uint32(rlim.Max) - } else { - return EINVAL - } - - return setrlimit(resource, &rl) -} - func (r *PtraceRegs) PC() uint32 { return r.Nip } func (r *PtraceRegs) SetPC(pc uint32) { r.Nip = pc } diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go b/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go index 4df56616b8..806aa2574d 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go @@ -34,7 +34,6 @@ package unix //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) //sys setfsgid(gid int) (prev int, err error) //sys setfsuid(uid int) (prev int, err error) -//sysnb Setrlimit(resource int, rlim *Rlimit) (err error) //sys Shutdown(fd int, how int) (err error) //sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) //sys Stat(path string, stat *Stat_t) (err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go b/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go index 5f4243dea2..5e6ceee129 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go @@ -32,13 +32,12 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err if timeout != nil { ts = &Timespec{Sec: timeout.Sec, Nsec: timeout.Usec * 1000} } - return Pselect(nfd, r, w, e, ts, nil) + return pselect6(nfd, r, w, e, ts, nil) } //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) //sys setfsgid(gid int) (prev int, err error) //sys setfsuid(uid int) (prev int, err error) -//sysnb Setrlimit(resource int, rlim *Rlimit) (err error) //sys Shutdown(fd int, how int) (err error) //sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) @@ -178,3 +177,14 @@ func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error } return kexecFileLoad(kernelFd, initrdFd, cmdlineLen, cmdline, flags) } + +//sys riscvHWProbe(pairs []RISCVHWProbePairs, cpuCount uintptr, cpus *CPUSet, flags uint) (err error) + +func RISCVHWProbe(pairs []RISCVHWProbePairs, set *CPUSet, flags uint) (err error) { + var setSize uintptr + + if set != nil { + setSize = uintptr(unsafe.Sizeof(*set)) + } + return riscvHWProbe(pairs, setSize, set, flags) +} diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go b/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go index d0a7d40668..2f89e8f5de 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go @@ -34,7 +34,6 @@ import ( //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) //sys setfsgid(gid int) (prev int, err error) //sys setfsuid(uid int) (prev int, err error) -//sysnb Setrlimit(resource int, rlim *Rlimit) (err error) //sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) //sys Stat(path string, stat *Stat_t) (err error) //sys Statfs(path string, buf *Statfs_t) (err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go b/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go index f5c793be26..7ca064ae76 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go @@ -31,7 +31,6 @@ package unix //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) //sys setfsgid(gid int) (prev int, err error) //sys setfsuid(uid int) (prev int, err error) -//sysnb Setrlimit(resource int, rlim *Rlimit) (err error) //sys Shutdown(fd int, how int) (err error) //sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) //sys Stat(path string, stat *Stat_t) (err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_netbsd.go b/vendor/golang.org/x/sys/unix/syscall_netbsd.go index e66865dccb..ddd1ac8534 100644 --- a/vendor/golang.org/x/sys/unix/syscall_netbsd.go +++ b/vendor/golang.org/x/sys/unix/syscall_netbsd.go @@ -340,7 +340,6 @@ func Statvfs(path string, buf *Statvfs_t) (err error) { //sys Setpriority(which int, who int, prio int) (err error) //sysnb Setregid(rgid int, egid int) (err error) //sysnb Setreuid(ruid int, euid int) (err error) -//sysnb Setrlimit(which int, lim *Rlimit) (err error) //sysnb Setsid() (pid int, err error) //sysnb Settimeofday(tp *Timeval) (err error) //sysnb Setuid(uid int) (err error) @@ -361,6 +360,18 @@ func Statvfs(path string, buf *Statvfs_t) (err error) { //sys writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE //sys utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) +const ( + mremapFixed = MAP_FIXED + mremapDontunmap = 0 + mremapMaymove = 0 +) + +//sys mremapNetBSD(oldp uintptr, oldsize uintptr, newp uintptr, newsize uintptr, flags int) (xaddr uintptr, err error) = SYS_MREMAP + +func mremap(oldaddr uintptr, oldlength uintptr, newlength uintptr, flags int, newaddr uintptr) (uintptr, error) { + return mremapNetBSD(oldaddr, oldlength, newaddr, newlength, flags) +} + /* * Unimplemented */ @@ -501,7 +512,6 @@ func Statvfs(path string, buf *Statvfs_t) (err error) { // compat_43_osendmsg // compat_43_osethostid // compat_43_osethostname -// compat_43_osetrlimit // compat_43_osigblock // compat_43_osigsetmask // compat_43_osigstack @@ -566,7 +576,6 @@ func Statvfs(path string, buf *Statvfs_t) (err error) { // mq_timedreceive // mq_timedsend // mq_unlink -// mremap // msgget // msgrcv // msgsnd diff --git a/vendor/golang.org/x/sys/unix/syscall_openbsd.go b/vendor/golang.org/x/sys/unix/syscall_openbsd.go index 5e9de23ae3..c5f166a115 100644 --- a/vendor/golang.org/x/sys/unix/syscall_openbsd.go +++ b/vendor/golang.org/x/sys/unix/syscall_openbsd.go @@ -151,6 +151,21 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { return } +//sysnb getresuid(ruid *_C_int, euid *_C_int, suid *_C_int) +//sysnb getresgid(rgid *_C_int, egid *_C_int, sgid *_C_int) + +func Getresuid() (ruid, euid, suid int) { + var r, e, s _C_int + getresuid(&r, &e, &s) + return int(r), int(e), int(s) +} + +func Getresgid() (rgid, egid, sgid int) { + var r, e, s _C_int + getresgid(&r, &e, &s) + return int(r), int(e), int(s) +} + //sys ioctl(fd int, req uint, arg uintptr) (err error) //sys ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) = SYS_IOCTL @@ -294,7 +309,6 @@ func Uname(uname *Utsname) error { //sysnb Setreuid(ruid int, euid int) (err error) //sysnb Setresgid(rgid int, egid int, sgid int) (err error) //sysnb Setresuid(ruid int, euid int, suid int) (err error) -//sysnb Setrlimit(which int, lim *Rlimit) (err error) //sysnb Setrtable(rtable int) (err error) //sysnb Setsid() (pid int, err error) //sysnb Settimeofday(tp *Timeval) (err error) @@ -339,8 +353,6 @@ func Uname(uname *Utsname) error { // getgid // getitimer // getlogin -// getresgid -// getresuid // getthrid // ktrace // lfs_bmapv diff --git a/vendor/golang.org/x/sys/unix/syscall_solaris.go b/vendor/golang.org/x/sys/unix/syscall_solaris.go index d3444b64d6..72d23575fa 100644 --- a/vendor/golang.org/x/sys/unix/syscall_solaris.go +++ b/vendor/golang.org/x/sys/unix/syscall_solaris.go @@ -545,24 +545,24 @@ func Minor(dev uint64) uint32 { * Expose the ioctl function */ -//sys ioctlRet(fd int, req uint, arg uintptr) (ret int, err error) = libc.ioctl -//sys ioctlPtrRet(fd int, req uint, arg unsafe.Pointer) (ret int, err error) = libc.ioctl +//sys ioctlRet(fd int, req int, arg uintptr) (ret int, err error) = libc.ioctl +//sys ioctlPtrRet(fd int, req int, arg unsafe.Pointer) (ret int, err error) = libc.ioctl -func ioctl(fd int, req uint, arg uintptr) (err error) { +func ioctl(fd int, req int, arg uintptr) (err error) { _, err = ioctlRet(fd, req, arg) return err } -func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { +func ioctlPtr(fd int, req int, arg unsafe.Pointer) (err error) { _, err = ioctlPtrRet(fd, req, arg) return err } -func IoctlSetTermio(fd int, req uint, value *Termio) error { +func IoctlSetTermio(fd int, req int, value *Termio) error { return ioctlPtr(fd, req, unsafe.Pointer(value)) } -func IoctlGetTermio(fd int, req uint) (*Termio, error) { +func IoctlGetTermio(fd int, req int) (*Termio, error) { var value Termio err := ioctlPtr(fd, req, unsafe.Pointer(&value)) return &value, err @@ -665,7 +665,6 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e //sys Setpriority(which int, who int, prio int) (err error) //sysnb Setregid(rgid int, egid int) (err error) //sysnb Setreuid(ruid int, euid int) (err error) -//sysnb Setrlimit(which int, lim *Rlimit) (err error) //sysnb Setsid() (pid int, err error) //sysnb Setuid(uid int) (err error) //sys Shutdown(s int, how int) (err error) = libsocket.shutdown @@ -717,20 +716,6 @@ func writelen(fd int, buf *byte, nbuf int) (n int, err error) { return } -var mapper = &mmapper{ - active: make(map[*byte][]byte), - mmap: mmap, - munmap: munmap, -} - -func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) { - return mapper.Mmap(fd, offset, length, prot, flags) -} - -func Munmap(b []byte) (err error) { - return mapper.Munmap(b) -} - // Event Ports type fileObjCookie struct { @@ -1080,11 +1065,11 @@ func Getmsg(fd int, cl []byte, data []byte) (retCl []byte, retData []byte, flags return retCl, retData, flags, nil } -func IoctlSetIntRetInt(fd int, req uint, arg int) (int, error) { +func IoctlSetIntRetInt(fd int, req int, arg int) (int, error) { return ioctlRet(fd, req, uintptr(arg)) } -func IoctlSetString(fd int, req uint, val string) error { +func IoctlSetString(fd int, req int, val string) error { bs := make([]byte, len(val)+1) copy(bs[:len(bs)-1], val) err := ioctlPtr(fd, req, unsafe.Pointer(&bs[0])) @@ -1120,7 +1105,7 @@ func (l *Lifreq) GetLifruUint() uint { return *(*uint)(unsafe.Pointer(&l.Lifru[0])) } -func IoctlLifreq(fd int, req uint, l *Lifreq) error { +func IoctlLifreq(fd int, req int, l *Lifreq) error { return ioctlPtr(fd, req, unsafe.Pointer(l)) } @@ -1131,6 +1116,6 @@ func (s *Strioctl) SetInt(i int) { s.Dp = (*int8)(unsafe.Pointer(&i)) } -func IoctlSetStrioctlRetInt(fd int, req uint, s *Strioctl) (int, error) { +func IoctlSetStrioctlRetInt(fd int, req int, s *Strioctl) (int, error) { return ioctlPtrRet(fd, req, unsafe.Pointer(s)) } diff --git a/vendor/golang.org/x/sys/unix/syscall_unix.go b/vendor/golang.org/x/sys/unix/syscall_unix.go index 00f0aa3758..8bb30e7ce3 100644 --- a/vendor/golang.org/x/sys/unix/syscall_unix.go +++ b/vendor/golang.org/x/sys/unix/syscall_unix.go @@ -147,6 +147,14 @@ func (m *mmapper) Munmap(data []byte) (err error) { return nil } +func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) { + return mapper.Mmap(fd, offset, length, prot, flags) +} + +func Munmap(b []byte) (err error) { + return mapper.Munmap(b) +} + func Read(fd int, p []byte) (n int, err error) { n, err = read(fd, p) if raceenabled { @@ -587,3 +595,10 @@ func emptyIovecs(iov []Iovec) bool { } return true } + +// Setrlimit sets a resource limit. +func Setrlimit(resource int, rlim *Rlimit) error { + // Just call the syscall version, because as of Go 1.21 + // it will affect starting a new process. + return syscall.Setrlimit(resource, (*syscall.Rlimit)(rlim)) +} diff --git a/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go b/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go index b295497ae4..44e72edb42 100644 --- a/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go +++ b/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go @@ -212,8 +212,8 @@ func (cmsg *Cmsghdr) SetLen(length int) { //sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) = SYS___SENDMSG_A //sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) = SYS_MMAP //sys munmap(addr uintptr, length uintptr) (err error) = SYS_MUNMAP -//sys ioctl(fd int, req uint, arg uintptr) (err error) = SYS_IOCTL -//sys ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) = SYS_IOCTL +//sys ioctl(fd int, req int, arg uintptr) (err error) = SYS_IOCTL +//sys ioctlPtr(fd int, req int, arg unsafe.Pointer) (err error) = SYS_IOCTL //sys Access(path string, mode uint32) (err error) = SYS___ACCESS_A //sys Chdir(path string) (err error) = SYS___CHDIR_A @@ -285,25 +285,11 @@ func Close(fd int) (err error) { return } -var mapper = &mmapper{ - active: make(map[*byte][]byte), - mmap: mmap, - munmap: munmap, -} - // Dummy function: there are no semantics for Madvise on z/OS func Madvise(b []byte, advice int) (err error) { return } -func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) { - return mapper.Mmap(fd, offset, length, prot, flags) -} - -func Munmap(b []byte) (err error) { - return mapper.Munmap(b) -} - //sys Gethostname(buf []byte) (err error) = SYS___GETHOSTNAME_A //sysnb Getegid() (egid int) //sysnb Geteuid() (uid int) diff --git a/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go index 476a1c7e77..1430076271 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go @@ -1270,6 +1270,16 @@ const ( SEEK_END = 0x2 SEEK_HOLE = 0x3 SEEK_SET = 0x0 + SF_APPEND = 0x40000 + SF_ARCHIVED = 0x10000 + SF_DATALESS = 0x40000000 + SF_FIRMLINK = 0x800000 + SF_IMMUTABLE = 0x20000 + SF_NOUNLINK = 0x100000 + SF_RESTRICTED = 0x80000 + SF_SETTABLE = 0x3fff0000 + SF_SUPPORTED = 0x9f0000 + SF_SYNTHETIC = 0xc0000000 SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 @@ -1543,6 +1553,15 @@ const ( TIOCTIMESTAMP = 0x40107459 TIOCUCNTL = 0x80047466 TOSTOP = 0x400000 + UF_APPEND = 0x4 + UF_COMPRESSED = 0x20 + UF_DATAVAULT = 0x80 + UF_HIDDEN = 0x8000 + UF_IMMUTABLE = 0x2 + UF_NODUMP = 0x1 + UF_OPAQUE = 0x8 + UF_SETTABLE = 0xffff + UF_TRACKED = 0x40 VDISCARD = 0xf VDSUSP = 0xb VEOF = 0x0 diff --git a/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go index e36f5178d6..ab044a7427 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go @@ -1270,6 +1270,16 @@ const ( SEEK_END = 0x2 SEEK_HOLE = 0x3 SEEK_SET = 0x0 + SF_APPEND = 0x40000 + SF_ARCHIVED = 0x10000 + SF_DATALESS = 0x40000000 + SF_FIRMLINK = 0x800000 + SF_IMMUTABLE = 0x20000 + SF_NOUNLINK = 0x100000 + SF_RESTRICTED = 0x80000 + SF_SETTABLE = 0x3fff0000 + SF_SUPPORTED = 0x9f0000 + SF_SYNTHETIC = 0xc0000000 SHUT_RD = 0x0 SHUT_RDWR = 0x2 SHUT_WR = 0x1 @@ -1543,6 +1553,15 @@ const ( TIOCTIMESTAMP = 0x40107459 TIOCUCNTL = 0x80047466 TOSTOP = 0x400000 + UF_APPEND = 0x4 + UF_COMPRESSED = 0x20 + UF_DATAVAULT = 0x80 + UF_HIDDEN = 0x8000 + UF_IMMUTABLE = 0x2 + UF_NODUMP = 0x1 + UF_OPAQUE = 0x8 + UF_SETTABLE = 0xffff + UF_TRACKED = 0x40 VDISCARD = 0xf VDSUSP = 0xb VEOF = 0x0 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux.go b/vendor/golang.org/x/sys/unix/zerrors_linux.go index 398c37e52d..3784f402e5 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux.go @@ -493,6 +493,7 @@ const ( BPF_F_TEST_RUN_ON_CPU = 0x1 BPF_F_TEST_STATE_FREQ = 0x8 BPF_F_TEST_XDP_LIVE_FRAMES = 0x2 + BPF_F_XDP_DEV_BOUND_ONLY = 0x40 BPF_F_XDP_HAS_FRAGS = 0x20 BPF_H = 0x8 BPF_IMM = 0x0 @@ -826,9 +827,9 @@ const ( DM_UUID_FLAG = 0x4000 DM_UUID_LEN = 0x81 DM_VERSION = 0xc138fd00 - DM_VERSION_EXTRA = "-ioctl (2022-07-28)" + DM_VERSION_EXTRA = "-ioctl (2023-03-01)" DM_VERSION_MAJOR = 0x4 - DM_VERSION_MINOR = 0x2f + DM_VERSION_MINOR = 0x30 DM_VERSION_PATCHLEVEL = 0x0 DT_BLK = 0x6 DT_CHR = 0x2 @@ -1197,6 +1198,7 @@ const ( FAN_EVENT_METADATA_LEN = 0x18 FAN_EVENT_ON_CHILD = 0x8000000 FAN_FS_ERROR = 0x8000 + FAN_INFO = 0x20 FAN_MARK_ADD = 0x1 FAN_MARK_DONT_FOLLOW = 0x4 FAN_MARK_EVICTABLE = 0x200 @@ -1233,6 +1235,8 @@ const ( FAN_REPORT_PIDFD = 0x80 FAN_REPORT_TARGET_FID = 0x1000 FAN_REPORT_TID = 0x100 + FAN_RESPONSE_INFO_AUDIT_RULE = 0x1 + FAN_RESPONSE_INFO_NONE = 0x0 FAN_UNLIMITED_MARKS = 0x20 FAN_UNLIMITED_QUEUE = 0x10 FD_CLOEXEC = 0x1 @@ -1860,6 +1864,7 @@ const ( MEMWRITEOOB64 = 0xc0184d15 MFD_ALLOW_SEALING = 0x2 MFD_CLOEXEC = 0x1 + MFD_EXEC = 0x10 MFD_HUGETLB = 0x4 MFD_HUGE_16GB = 0x88000000 MFD_HUGE_16MB = 0x60000000 @@ -1875,6 +1880,7 @@ const ( MFD_HUGE_8MB = 0x5c000000 MFD_HUGE_MASK = 0x3f MFD_HUGE_SHIFT = 0x1a + MFD_NOEXEC_SEAL = 0x8 MINIX2_SUPER_MAGIC = 0x2468 MINIX2_SUPER_MAGIC2 = 0x2478 MINIX3_SUPER_MAGIC = 0x4d5a @@ -1898,6 +1904,9 @@ const ( MOUNT_ATTR_SIZE_VER0 = 0x20 MOUNT_ATTR_STRICTATIME = 0x20 MOUNT_ATTR__ATIME = 0x70 + MREMAP_DONTUNMAP = 0x4 + MREMAP_FIXED = 0x2 + MREMAP_MAYMOVE = 0x1 MSDOS_SUPER_MAGIC = 0x4d44 MSG_BATCH = 0x40000 MSG_CMSG_CLOEXEC = 0x40000000 @@ -2204,6 +2213,7 @@ const ( PACKET_USER = 0x6 PACKET_VERSION = 0xa PACKET_VNET_HDR = 0xf + PACKET_VNET_HDR_SZ = 0x18 PARITY_CRC16_PR0 = 0x2 PARITY_CRC16_PR0_CCITT = 0x4 PARITY_CRC16_PR1 = 0x3 @@ -2221,6 +2231,7 @@ const ( PERF_ATTR_SIZE_VER5 = 0x70 PERF_ATTR_SIZE_VER6 = 0x78 PERF_ATTR_SIZE_VER7 = 0x80 + PERF_ATTR_SIZE_VER8 = 0x88 PERF_AUX_FLAG_COLLISION = 0x8 PERF_AUX_FLAG_CORESIGHT_FORMAT_CORESIGHT = 0x0 PERF_AUX_FLAG_CORESIGHT_FORMAT_RAW = 0x100 @@ -2361,6 +2372,7 @@ const ( PR_FP_EXC_UND = 0x40000 PR_FP_MODE_FR = 0x1 PR_FP_MODE_FRE = 0x2 + PR_GET_AUXV = 0x41555856 PR_GET_CHILD_SUBREAPER = 0x25 PR_GET_DUMPABLE = 0x3 PR_GET_ENDIAN = 0x13 @@ -2369,6 +2381,8 @@ const ( PR_GET_FP_MODE = 0x2e PR_GET_IO_FLUSHER = 0x3a PR_GET_KEEPCAPS = 0x7 + PR_GET_MDWE = 0x42 + PR_GET_MEMORY_MERGE = 0x44 PR_GET_NAME = 0x10 PR_GET_NO_NEW_PRIVS = 0x27 PR_GET_PDEATHSIG = 0x2 @@ -2389,6 +2403,7 @@ const ( PR_MCE_KILL_GET = 0x22 PR_MCE_KILL_LATE = 0x0 PR_MCE_KILL_SET = 0x1 + PR_MDWE_REFUSE_EXEC_GAIN = 0x1 PR_MPX_DISABLE_MANAGEMENT = 0x2c PR_MPX_ENABLE_MANAGEMENT = 0x2b PR_MTE_TAG_MASK = 0x7fff8 @@ -2423,6 +2438,8 @@ const ( PR_SET_FP_MODE = 0x2d PR_SET_IO_FLUSHER = 0x39 PR_SET_KEEPCAPS = 0x8 + PR_SET_MDWE = 0x41 + PR_SET_MEMORY_MERGE = 0x43 PR_SET_MM = 0x23 PR_SET_MM_ARG_END = 0x9 PR_SET_MM_ARG_START = 0x8 @@ -2506,6 +2523,7 @@ const ( PTRACE_GETSIGMASK = 0x420a PTRACE_GET_RSEQ_CONFIGURATION = 0x420f PTRACE_GET_SYSCALL_INFO = 0x420e + PTRACE_GET_SYSCALL_USER_DISPATCH_CONFIG = 0x4211 PTRACE_INTERRUPT = 0x4207 PTRACE_KILL = 0x8 PTRACE_LISTEN = 0x4208 @@ -2536,6 +2554,7 @@ const ( PTRACE_SETREGSET = 0x4205 PTRACE_SETSIGINFO = 0x4203 PTRACE_SETSIGMASK = 0x420b + PTRACE_SET_SYSCALL_USER_DISPATCH_CONFIG = 0x4210 PTRACE_SINGLESTEP = 0x9 PTRACE_SYSCALL = 0x18 PTRACE_SYSCALL_INFO_ENTRY = 0x1 @@ -2967,6 +2986,7 @@ const ( SOL_TCP = 0x6 SOL_TIPC = 0x10f SOL_TLS = 0x11a + SOL_UDP = 0x11 SOL_X25 = 0x106 SOL_XDP = 0x11b SOMAXCONN = 0x1000 @@ -3071,7 +3091,7 @@ const ( TASKSTATS_GENL_NAME = "TASKSTATS" TASKSTATS_GENL_VERSION = 0x1 TASKSTATS_TYPE_MAX = 0x6 - TASKSTATS_VERSION = 0xd + TASKSTATS_VERSION = 0xe TCIFLUSH = 0x0 TCIOFF = 0x2 TCIOFLUSH = 0x2 @@ -3237,6 +3257,7 @@ const ( TP_STATUS_COPY = 0x2 TP_STATUS_CSUMNOTREADY = 0x8 TP_STATUS_CSUM_VALID = 0x80 + TP_STATUS_GSO_TCP = 0x100 TP_STATUS_KERNEL = 0x0 TP_STATUS_LOSING = 0x4 TP_STATUS_SENDING = 0x2 @@ -3251,6 +3272,19 @@ const ( TRACEFS_MAGIC = 0x74726163 TS_COMM_LEN = 0x20 UDF_SUPER_MAGIC = 0x15013346 + UDP_CORK = 0x1 + UDP_ENCAP = 0x64 + UDP_ENCAP_ESPINUDP = 0x2 + UDP_ENCAP_ESPINUDP_NON_IKE = 0x1 + UDP_ENCAP_GTP0 = 0x4 + UDP_ENCAP_GTP1U = 0x5 + UDP_ENCAP_L2TPINUDP = 0x3 + UDP_GRO = 0x68 + UDP_NO_CHECK6_RX = 0x66 + UDP_NO_CHECK6_TX = 0x65 + UDP_SEGMENT = 0x67 + UDP_V4_FLOW = 0x2 + UDP_V6_FLOW = 0x6 UMOUNT_NOFOLLOW = 0x8 USBDEVICE_SUPER_MAGIC = 0x9fa2 UTIME_NOW = 0x3fffffff diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go index a46df0f1e5..cfb1430018 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go @@ -27,22 +27,31 @@ const ( B57600 = 0x1001 B576000 = 0x1006 B921600 = 0x1007 + BLKALIGNOFF = 0x127a BLKBSZGET = 0x80041270 BLKBSZSET = 0x40041271 + BLKDISCARD = 0x1277 + BLKDISCARDZEROES = 0x127c BLKFLSBUF = 0x1261 BLKFRAGET = 0x1265 BLKFRASET = 0x1264 + BLKGETDISKSEQ = 0x80081280 BLKGETSIZE = 0x1260 BLKGETSIZE64 = 0x80041272 + BLKIOMIN = 0x1278 + BLKIOOPT = 0x1279 BLKPBSZGET = 0x127b BLKRAGET = 0x1263 BLKRASET = 0x1262 BLKROGET = 0x125e BLKROSET = 0x125d + BLKROTATIONAL = 0x127e BLKRRPART = 0x125f + BLKSECDISCARD = 0x127d BLKSECTGET = 0x1267 BLKSECTSET = 0x1266 BLKSSZGET = 0x1268 + BLKZEROOUT = 0x127f BOTHER = 0x1000 BS1 = 0x2000 BSDLY = 0x2000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go index 6cd4a3ea9d..df64f2d590 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go @@ -27,22 +27,31 @@ const ( B57600 = 0x1001 B576000 = 0x1006 B921600 = 0x1007 + BLKALIGNOFF = 0x127a BLKBSZGET = 0x80081270 BLKBSZSET = 0x40081271 + BLKDISCARD = 0x1277 + BLKDISCARDZEROES = 0x127c BLKFLSBUF = 0x1261 BLKFRAGET = 0x1265 BLKFRASET = 0x1264 + BLKGETDISKSEQ = 0x80081280 BLKGETSIZE = 0x1260 BLKGETSIZE64 = 0x80081272 + BLKIOMIN = 0x1278 + BLKIOOPT = 0x1279 BLKPBSZGET = 0x127b BLKRAGET = 0x1263 BLKRASET = 0x1262 BLKROGET = 0x125e BLKROSET = 0x125d + BLKROTATIONAL = 0x127e BLKRRPART = 0x125f + BLKSECDISCARD = 0x127d BLKSECTGET = 0x1267 BLKSECTSET = 0x1266 BLKSSZGET = 0x1268 + BLKZEROOUT = 0x127f BOTHER = 0x1000 BS1 = 0x2000 BSDLY = 0x2000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go index c7ebee24df..3025cd5b2d 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go @@ -27,22 +27,31 @@ const ( B57600 = 0x1001 B576000 = 0x1006 B921600 = 0x1007 + BLKALIGNOFF = 0x127a BLKBSZGET = 0x80041270 BLKBSZSET = 0x40041271 + BLKDISCARD = 0x1277 + BLKDISCARDZEROES = 0x127c BLKFLSBUF = 0x1261 BLKFRAGET = 0x1265 BLKFRASET = 0x1264 + BLKGETDISKSEQ = 0x80081280 BLKGETSIZE = 0x1260 BLKGETSIZE64 = 0x80041272 + BLKIOMIN = 0x1278 + BLKIOOPT = 0x1279 BLKPBSZGET = 0x127b BLKRAGET = 0x1263 BLKRASET = 0x1262 BLKROGET = 0x125e BLKROSET = 0x125d + BLKROTATIONAL = 0x127e BLKRRPART = 0x125f + BLKSECDISCARD = 0x127d BLKSECTGET = 0x1267 BLKSECTSET = 0x1266 BLKSSZGET = 0x1268 + BLKZEROOUT = 0x127f BOTHER = 0x1000 BS1 = 0x2000 BSDLY = 0x2000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go index 9d5352c3e4..09e1ffbef9 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go @@ -27,22 +27,31 @@ const ( B57600 = 0x1001 B576000 = 0x1006 B921600 = 0x1007 + BLKALIGNOFF = 0x127a BLKBSZGET = 0x80081270 BLKBSZSET = 0x40081271 + BLKDISCARD = 0x1277 + BLKDISCARDZEROES = 0x127c BLKFLSBUF = 0x1261 BLKFRAGET = 0x1265 BLKFRASET = 0x1264 + BLKGETDISKSEQ = 0x80081280 BLKGETSIZE = 0x1260 BLKGETSIZE64 = 0x80081272 + BLKIOMIN = 0x1278 + BLKIOOPT = 0x1279 BLKPBSZGET = 0x127b BLKRAGET = 0x1263 BLKRASET = 0x1262 BLKROGET = 0x125e BLKROSET = 0x125d + BLKROTATIONAL = 0x127e BLKRRPART = 0x125f + BLKSECDISCARD = 0x127d BLKSECTGET = 0x1267 BLKSECTSET = 0x1266 BLKSSZGET = 0x1268 + BLKZEROOUT = 0x127f BOTHER = 0x1000 BS1 = 0x2000 BSDLY = 0x2000 @@ -443,6 +452,7 @@ const ( TIOCSWINSZ = 0x5414 TIOCVHANGUP = 0x5437 TOSTOP = 0x100 + TPIDR2_MAGIC = 0x54504902 TUNATTACHFILTER = 0x401054d5 TUNDETACHFILTER = 0x401054d6 TUNGETDEVNETNS = 0x54e3 @@ -515,6 +525,7 @@ const ( XCASE = 0x4 XTABS = 0x1800 ZA_MAGIC = 0x54366345 + ZT_MAGIC = 0x5a544e01 _HIDIOCGRAWNAME = 0x80804804 _HIDIOCGRAWPHYS = 0x80404805 _HIDIOCGRAWUNIQ = 0x80404808 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go index f26a164f4a..a457235407 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go @@ -27,22 +27,31 @@ const ( B57600 = 0x1001 B576000 = 0x1006 B921600 = 0x1007 + BLKALIGNOFF = 0x127a BLKBSZGET = 0x80081270 BLKBSZSET = 0x40081271 + BLKDISCARD = 0x1277 + BLKDISCARDZEROES = 0x127c BLKFLSBUF = 0x1261 BLKFRAGET = 0x1265 BLKFRASET = 0x1264 + BLKGETDISKSEQ = 0x80081280 BLKGETSIZE = 0x1260 BLKGETSIZE64 = 0x80081272 + BLKIOMIN = 0x1278 + BLKIOOPT = 0x1279 BLKPBSZGET = 0x127b BLKRAGET = 0x1263 BLKRASET = 0x1262 BLKROGET = 0x125e BLKROSET = 0x125d + BLKROTATIONAL = 0x127e BLKRRPART = 0x125f + BLKSECDISCARD = 0x127d BLKSECTGET = 0x1267 BLKSECTSET = 0x1266 BLKSSZGET = 0x1268 + BLKZEROOUT = 0x127f BOTHER = 0x1000 BS1 = 0x2000 BSDLY = 0x2000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go index 890bc3c9b7..fee7dfb819 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go @@ -27,22 +27,31 @@ const ( B57600 = 0x1001 B576000 = 0x1006 B921600 = 0x1007 + BLKALIGNOFF = 0x2000127a BLKBSZGET = 0x40041270 BLKBSZSET = 0x80041271 + BLKDISCARD = 0x20001277 + BLKDISCARDZEROES = 0x2000127c BLKFLSBUF = 0x20001261 BLKFRAGET = 0x20001265 BLKFRASET = 0x20001264 + BLKGETDISKSEQ = 0x40081280 BLKGETSIZE = 0x20001260 BLKGETSIZE64 = 0x40041272 + BLKIOMIN = 0x20001278 + BLKIOOPT = 0x20001279 BLKPBSZGET = 0x2000127b BLKRAGET = 0x20001263 BLKRASET = 0x20001262 BLKROGET = 0x2000125e BLKROSET = 0x2000125d + BLKROTATIONAL = 0x2000127e BLKRRPART = 0x2000125f + BLKSECDISCARD = 0x2000127d BLKSECTGET = 0x20001267 BLKSECTSET = 0x20001266 BLKSSZGET = 0x20001268 + BLKZEROOUT = 0x2000127f BOTHER = 0x1000 BS1 = 0x2000 BSDLY = 0x2000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go index 549f26ac64..a5b2373aea 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go @@ -27,22 +27,31 @@ const ( B57600 = 0x1001 B576000 = 0x1006 B921600 = 0x1007 + BLKALIGNOFF = 0x2000127a BLKBSZGET = 0x40081270 BLKBSZSET = 0x80081271 + BLKDISCARD = 0x20001277 + BLKDISCARDZEROES = 0x2000127c BLKFLSBUF = 0x20001261 BLKFRAGET = 0x20001265 BLKFRASET = 0x20001264 + BLKGETDISKSEQ = 0x40081280 BLKGETSIZE = 0x20001260 BLKGETSIZE64 = 0x40081272 + BLKIOMIN = 0x20001278 + BLKIOOPT = 0x20001279 BLKPBSZGET = 0x2000127b BLKRAGET = 0x20001263 BLKRASET = 0x20001262 BLKROGET = 0x2000125e BLKROSET = 0x2000125d + BLKROTATIONAL = 0x2000127e BLKRRPART = 0x2000125f + BLKSECDISCARD = 0x2000127d BLKSECTGET = 0x20001267 BLKSECTSET = 0x20001266 BLKSSZGET = 0x20001268 + BLKZEROOUT = 0x2000127f BOTHER = 0x1000 BS1 = 0x2000 BSDLY = 0x2000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go index e0365e32c1..5dde82c98a 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go @@ -27,22 +27,31 @@ const ( B57600 = 0x1001 B576000 = 0x1006 B921600 = 0x1007 + BLKALIGNOFF = 0x2000127a BLKBSZGET = 0x40081270 BLKBSZSET = 0x80081271 + BLKDISCARD = 0x20001277 + BLKDISCARDZEROES = 0x2000127c BLKFLSBUF = 0x20001261 BLKFRAGET = 0x20001265 BLKFRASET = 0x20001264 + BLKGETDISKSEQ = 0x40081280 BLKGETSIZE = 0x20001260 BLKGETSIZE64 = 0x40081272 + BLKIOMIN = 0x20001278 + BLKIOOPT = 0x20001279 BLKPBSZGET = 0x2000127b BLKRAGET = 0x20001263 BLKRASET = 0x20001262 BLKROGET = 0x2000125e BLKROSET = 0x2000125d + BLKROTATIONAL = 0x2000127e BLKRRPART = 0x2000125f + BLKSECDISCARD = 0x2000127d BLKSECTGET = 0x20001267 BLKSECTSET = 0x20001266 BLKSSZGET = 0x20001268 + BLKZEROOUT = 0x2000127f BOTHER = 0x1000 BS1 = 0x2000 BSDLY = 0x2000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go index fdccce15ca..2e80ea6b33 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go @@ -27,22 +27,31 @@ const ( B57600 = 0x1001 B576000 = 0x1006 B921600 = 0x1007 + BLKALIGNOFF = 0x2000127a BLKBSZGET = 0x40041270 BLKBSZSET = 0x80041271 + BLKDISCARD = 0x20001277 + BLKDISCARDZEROES = 0x2000127c BLKFLSBUF = 0x20001261 BLKFRAGET = 0x20001265 BLKFRASET = 0x20001264 + BLKGETDISKSEQ = 0x40081280 BLKGETSIZE = 0x20001260 BLKGETSIZE64 = 0x40041272 + BLKIOMIN = 0x20001278 + BLKIOOPT = 0x20001279 BLKPBSZGET = 0x2000127b BLKRAGET = 0x20001263 BLKRASET = 0x20001262 BLKROGET = 0x2000125e BLKROSET = 0x2000125d + BLKROTATIONAL = 0x2000127e BLKRRPART = 0x2000125f + BLKSECDISCARD = 0x2000127d BLKSECTGET = 0x20001267 BLKSECTSET = 0x20001266 BLKSSZGET = 0x20001268 + BLKZEROOUT = 0x2000127f BOTHER = 0x1000 BS1 = 0x2000 BSDLY = 0x2000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go index b2205c83fa..a65dcd7cbe 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go @@ -27,22 +27,31 @@ const ( B57600 = 0x10 B576000 = 0x15 B921600 = 0x16 + BLKALIGNOFF = 0x2000127a BLKBSZGET = 0x40041270 BLKBSZSET = 0x80041271 + BLKDISCARD = 0x20001277 + BLKDISCARDZEROES = 0x2000127c BLKFLSBUF = 0x20001261 BLKFRAGET = 0x20001265 BLKFRASET = 0x20001264 + BLKGETDISKSEQ = 0x40081280 BLKGETSIZE = 0x20001260 BLKGETSIZE64 = 0x40041272 + BLKIOMIN = 0x20001278 + BLKIOOPT = 0x20001279 BLKPBSZGET = 0x2000127b BLKRAGET = 0x20001263 BLKRASET = 0x20001262 BLKROGET = 0x2000125e BLKROSET = 0x2000125d + BLKROTATIONAL = 0x2000127e BLKRRPART = 0x2000125f + BLKSECDISCARD = 0x2000127d BLKSECTGET = 0x20001267 BLKSECTSET = 0x20001266 BLKSSZGET = 0x20001268 + BLKZEROOUT = 0x2000127f BOTHER = 0x1f BS1 = 0x8000 BSDLY = 0x8000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go index 81aa5ad0f6..cbd34e3d89 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go @@ -27,22 +27,31 @@ const ( B57600 = 0x10 B576000 = 0x15 B921600 = 0x16 + BLKALIGNOFF = 0x2000127a BLKBSZGET = 0x40081270 BLKBSZSET = 0x80081271 + BLKDISCARD = 0x20001277 + BLKDISCARDZEROES = 0x2000127c BLKFLSBUF = 0x20001261 BLKFRAGET = 0x20001265 BLKFRASET = 0x20001264 + BLKGETDISKSEQ = 0x40081280 BLKGETSIZE = 0x20001260 BLKGETSIZE64 = 0x40081272 + BLKIOMIN = 0x20001278 + BLKIOOPT = 0x20001279 BLKPBSZGET = 0x2000127b BLKRAGET = 0x20001263 BLKRASET = 0x20001262 BLKROGET = 0x2000125e BLKROSET = 0x2000125d + BLKROTATIONAL = 0x2000127e BLKRRPART = 0x2000125f + BLKSECDISCARD = 0x2000127d BLKSECTGET = 0x20001267 BLKSECTSET = 0x20001266 BLKSSZGET = 0x20001268 + BLKZEROOUT = 0x2000127f BOTHER = 0x1f BS1 = 0x8000 BSDLY = 0x8000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go index 76807a1fd4..e4afa7a317 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go @@ -27,22 +27,31 @@ const ( B57600 = 0x10 B576000 = 0x15 B921600 = 0x16 + BLKALIGNOFF = 0x2000127a BLKBSZGET = 0x40081270 BLKBSZSET = 0x80081271 + BLKDISCARD = 0x20001277 + BLKDISCARDZEROES = 0x2000127c BLKFLSBUF = 0x20001261 BLKFRAGET = 0x20001265 BLKFRASET = 0x20001264 + BLKGETDISKSEQ = 0x40081280 BLKGETSIZE = 0x20001260 BLKGETSIZE64 = 0x40081272 + BLKIOMIN = 0x20001278 + BLKIOOPT = 0x20001279 BLKPBSZGET = 0x2000127b BLKRAGET = 0x20001263 BLKRASET = 0x20001262 BLKROGET = 0x2000125e BLKROSET = 0x2000125d + BLKROTATIONAL = 0x2000127e BLKRRPART = 0x2000125f + BLKSECDISCARD = 0x2000127d BLKSECTGET = 0x20001267 BLKSECTSET = 0x20001266 BLKSSZGET = 0x20001268 + BLKZEROOUT = 0x2000127f BOTHER = 0x1f BS1 = 0x8000 BSDLY = 0x8000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go index d4a5ab9e4e..44f45a039d 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go @@ -27,22 +27,31 @@ const ( B57600 = 0x1001 B576000 = 0x1006 B921600 = 0x1007 + BLKALIGNOFF = 0x127a BLKBSZGET = 0x80081270 BLKBSZSET = 0x40081271 + BLKDISCARD = 0x1277 + BLKDISCARDZEROES = 0x127c BLKFLSBUF = 0x1261 BLKFRAGET = 0x1265 BLKFRASET = 0x1264 + BLKGETDISKSEQ = 0x80081280 BLKGETSIZE = 0x1260 BLKGETSIZE64 = 0x80081272 + BLKIOMIN = 0x1278 + BLKIOOPT = 0x1279 BLKPBSZGET = 0x127b BLKRAGET = 0x1263 BLKRASET = 0x1262 BLKROGET = 0x125e BLKROSET = 0x125d + BLKROTATIONAL = 0x127e BLKRRPART = 0x125f + BLKSECDISCARD = 0x127d BLKSECTGET = 0x1267 BLKSECTSET = 0x1266 BLKSSZGET = 0x1268 + BLKZEROOUT = 0x127f BOTHER = 0x1000 BS1 = 0x2000 BSDLY = 0x2000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go index 66e65db951..74733e260f 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go @@ -27,22 +27,31 @@ const ( B57600 = 0x1001 B576000 = 0x1006 B921600 = 0x1007 + BLKALIGNOFF = 0x127a BLKBSZGET = 0x80081270 BLKBSZSET = 0x40081271 + BLKDISCARD = 0x1277 + BLKDISCARDZEROES = 0x127c BLKFLSBUF = 0x1261 BLKFRAGET = 0x1265 BLKFRASET = 0x1264 + BLKGETDISKSEQ = 0x80081280 BLKGETSIZE = 0x1260 BLKGETSIZE64 = 0x80081272 + BLKIOMIN = 0x1278 + BLKIOOPT = 0x1279 BLKPBSZGET = 0x127b BLKRAGET = 0x1263 BLKRASET = 0x1262 BLKROGET = 0x125e BLKROSET = 0x125d + BLKROTATIONAL = 0x127e BLKRRPART = 0x125f + BLKSECDISCARD = 0x127d BLKSECTGET = 0x1267 BLKSECTSET = 0x1266 BLKSSZGET = 0x1268 + BLKZEROOUT = 0x127f BOTHER = 0x1000 BS1 = 0x2000 BSDLY = 0x2000 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go index f619252691..f5f3934b1a 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go @@ -30,22 +30,31 @@ const ( B57600 = 0x1001 B576000 = 0x1006 B921600 = 0x1007 + BLKALIGNOFF = 0x2000127a BLKBSZGET = 0x40081270 BLKBSZSET = 0x80081271 + BLKDISCARD = 0x20001277 + BLKDISCARDZEROES = 0x2000127c BLKFLSBUF = 0x20001261 BLKFRAGET = 0x20001265 BLKFRASET = 0x20001264 + BLKGETDISKSEQ = 0x40081280 BLKGETSIZE = 0x20001260 BLKGETSIZE64 = 0x40081272 + BLKIOMIN = 0x20001278 + BLKIOOPT = 0x20001279 BLKPBSZGET = 0x2000127b BLKRAGET = 0x20001263 BLKRASET = 0x20001262 BLKROGET = 0x2000125e BLKROSET = 0x2000125d + BLKROTATIONAL = 0x2000127e BLKRRPART = 0x2000125f + BLKSECDISCARD = 0x2000127d BLKSECTGET = 0x20001267 BLKSECTSET = 0x20001266 BLKSSZGET = 0x20001268 + BLKZEROOUT = 0x2000127f BOTHER = 0x1000 BS1 = 0x2000 BSDLY = 0x2000 @@ -329,6 +338,54 @@ const ( SCM_WIFI_STATUS = 0x25 SFD_CLOEXEC = 0x400000 SFD_NONBLOCK = 0x4000 + SF_FP = 0x38 + SF_I0 = 0x20 + SF_I1 = 0x24 + SF_I2 = 0x28 + SF_I3 = 0x2c + SF_I4 = 0x30 + SF_I5 = 0x34 + SF_L0 = 0x0 + SF_L1 = 0x4 + SF_L2 = 0x8 + SF_L3 = 0xc + SF_L4 = 0x10 + SF_L5 = 0x14 + SF_L6 = 0x18 + SF_L7 = 0x1c + SF_PC = 0x3c + SF_RETP = 0x40 + SF_V9_FP = 0x70 + SF_V9_I0 = 0x40 + SF_V9_I1 = 0x48 + SF_V9_I2 = 0x50 + SF_V9_I3 = 0x58 + SF_V9_I4 = 0x60 + SF_V9_I5 = 0x68 + SF_V9_L0 = 0x0 + SF_V9_L1 = 0x8 + SF_V9_L2 = 0x10 + SF_V9_L3 = 0x18 + SF_V9_L4 = 0x20 + SF_V9_L5 = 0x28 + SF_V9_L6 = 0x30 + SF_V9_L7 = 0x38 + SF_V9_PC = 0x78 + SF_V9_RETP = 0x80 + SF_V9_XARG0 = 0x88 + SF_V9_XARG1 = 0x90 + SF_V9_XARG2 = 0x98 + SF_V9_XARG3 = 0xa0 + SF_V9_XARG4 = 0xa8 + SF_V9_XARG5 = 0xb0 + SF_V9_XXARG = 0xb8 + SF_XARG0 = 0x44 + SF_XARG1 = 0x48 + SF_XARG2 = 0x4c + SF_XARG3 = 0x50 + SF_XARG4 = 0x54 + SF_XARG5 = 0x58 + SF_XXARG = 0x5c SIOCATMARK = 0x8905 SIOCGPGRP = 0x8904 SIOCGSTAMPNS_NEW = 0x40108907 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc.go b/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc.go index ef9dcd1bef..9a257219d7 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc.go @@ -124,7 +124,6 @@ int utime(uintptr_t, uintptr_t); unsigned long long getsystemcfg(int); int umount(uintptr_t); int getrlimit64(int, uintptr_t); -int setrlimit64(int, uintptr_t); long long lseek64(int, long long, int); uintptr_t mmap(uintptr_t, uintptr_t, int, int, int, long long); @@ -213,7 +212,7 @@ func wait4(pid Pid_t, status *_C_int, options int, rusage *Rusage) (wpid Pid_t, // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func ioctl(fd int, req uint, arg uintptr) (err error) { +func ioctl(fd int, req int, arg uintptr) (err error) { r0, er := C.ioctl(C.int(fd), C.int(req), C.uintptr_t(arg)) if r0 == -1 && er != nil { err = er @@ -223,7 +222,7 @@ func ioctl(fd int, req uint, arg uintptr) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { +func ioctlPtr(fd int, req int, arg unsafe.Pointer) (err error) { r0, er := C.ioctl(C.int(fd), C.int(req), C.uintptr_t(uintptr(arg))) if r0 == -1 && er != nil { err = er @@ -1464,16 +1463,6 @@ func Getrlimit(resource int, rlim *Rlimit) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Setrlimit(resource int, rlim *Rlimit) (err error) { - r0, er := C.setrlimit64(C.int(resource), C.uintptr_t(uintptr(unsafe.Pointer(rlim)))) - if r0 == -1 && er != nil { - err = er - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Seek(fd int, offset int64, whence int) (off int64, err error) { r0, er := C.lseek64(C.int(fd), C.longlong(offset), C.int(whence)) off = int64(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64.go b/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64.go index f86a945923..6de80c20cf 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64.go @@ -93,8 +93,8 @@ func wait4(pid Pid_t, status *_C_int, options int, rusage *Rusage) (wpid Pid_t, // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func ioctl(fd int, req uint, arg uintptr) (err error) { - _, e1 := callioctl(fd, int(req), arg) +func ioctl(fd int, req int, arg uintptr) (err error) { + _, e1 := callioctl(fd, req, arg) if e1 != 0 { err = errnoErr(e1) } @@ -103,8 +103,8 @@ func ioctl(fd int, req uint, arg uintptr) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { - _, e1 := callioctl_ptr(fd, int(req), arg) +func ioctlPtr(fd int, req int, arg unsafe.Pointer) (err error) { + _, e1 := callioctl_ptr(fd, req, arg) if e1 != 0 { err = errnoErr(e1) } @@ -1422,16 +1422,6 @@ func Getrlimit(resource int, rlim *Rlimit) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Setrlimit(resource int, rlim *Rlimit) (err error) { - _, e1 := callsetrlimit(resource, uintptr(unsafe.Pointer(rlim))) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Seek(fd int, offset int64, whence int) (off int64, err error) { r0, e1 := calllseek(fd, offset, whence) off = int64(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gc.go b/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gc.go index d32a84cae2..c4d50ae500 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gc.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gc.go @@ -124,7 +124,6 @@ import ( //go:cgo_import_dynamic libc_getsystemcfg getsystemcfg "libc.a/shr_64.o" //go:cgo_import_dynamic libc_umount umount "libc.a/shr_64.o" //go:cgo_import_dynamic libc_getrlimit getrlimit "libc.a/shr_64.o" -//go:cgo_import_dynamic libc_setrlimit setrlimit "libc.a/shr_64.o" //go:cgo_import_dynamic libc_lseek lseek "libc.a/shr_64.o" //go:cgo_import_dynamic libc_mmap64 mmap64 "libc.a/shr_64.o" @@ -242,7 +241,6 @@ import ( //go:linkname libc_getsystemcfg libc_getsystemcfg //go:linkname libc_umount libc_umount //go:linkname libc_getrlimit libc_getrlimit -//go:linkname libc_setrlimit libc_setrlimit //go:linkname libc_lseek libc_lseek //go:linkname libc_mmap64 libc_mmap64 @@ -363,7 +361,6 @@ var ( libc_getsystemcfg, libc_umount, libc_getrlimit, - libc_setrlimit, libc_lseek, libc_mmap64 syscallFunc ) @@ -1179,13 +1176,6 @@ func callgetrlimit(resource int, rlim uintptr) (r1 uintptr, e1 Errno) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func callsetrlimit(resource int, rlim uintptr) (r1 uintptr, e1 Errno) { - r1, _, e1 = rawSyscall6(uintptr(unsafe.Pointer(&libc_setrlimit)), 2, uintptr(resource), rlim, 0, 0, 0, 0) - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func calllseek(fd int, offset int64, whence int) (r1 uintptr, e1 Errno) { r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_lseek)), 3, uintptr(fd), uintptr(offset), uintptr(whence), 0, 0, 0) return diff --git a/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gccgo.go b/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gccgo.go index d7d8baf819..6903d3b09e 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gccgo.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64_gccgo.go @@ -123,7 +123,6 @@ int utime(uintptr_t, uintptr_t); unsigned long long getsystemcfg(int); int umount(uintptr_t); int getrlimit(int, uintptr_t); -int setrlimit(int, uintptr_t); long long lseek(int, long long, int); uintptr_t mmap64(uintptr_t, uintptr_t, int, int, int, long long); @@ -131,6 +130,7 @@ uintptr_t mmap64(uintptr_t, uintptr_t, int, int, int, long long); import "C" import ( "syscall" + "unsafe" ) // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -1055,14 +1055,6 @@ func callgetrlimit(resource int, rlim uintptr) (r1 uintptr, e1 Errno) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func callsetrlimit(resource int, rlim uintptr) (r1 uintptr, e1 Errno) { - r1 = uintptr(C.setrlimit(C.int(resource), C.uintptr_t(rlim))) - e1 = syscall.GetErrno() - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func calllseek(fd int, offset int64, whence int) (r1 uintptr, e1 Errno) { r1 = uintptr(C.lseek(C.int(fd), C.longlong(offset), C.int(whence))) e1 = syscall.GetErrno() diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go index a29ffdd566..4037ccf7a9 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go @@ -1992,6 +1992,31 @@ var libc_select_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Setattrlist(path string, attrlist *Attrlist, attrBuf []byte, options int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(attrBuf) > 0 { + _p1 = unsafe.Pointer(&attrBuf[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + _, _, e1 := syscall_syscall6(libc_setattrlist_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(attrlist)), uintptr(_p1), uintptr(len(attrBuf)), uintptr(options), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_setattrlist_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setattrlist setattrlist "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Setegid(egid int) (err error) { _, _, e1 := syscall_syscall(libc_setegid_trampoline_addr, uintptr(egid), 0, 0) if e1 != 0 { @@ -2123,20 +2148,6 @@ var libc_setreuid_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Setrlimit(which int, lim *Rlimit) (err error) { - _, _, e1 := syscall_rawSyscall(libc_setrlimit_trampoline_addr, uintptr(which), uintptr(unsafe.Pointer(lim)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -var libc_setrlimit_trampoline_addr uintptr - -//go:cgo_import_dynamic libc_setrlimit setrlimit "/usr/lib/libSystem.B.dylib" - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Setsid() (pid int, err error) { r0, _, e1 := syscall_rawSyscall(libc_setsid_trampoline_addr, 0, 0, 0) pid = int(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s index 95fe4c0eb9..4baaed0bc1 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s @@ -705,6 +705,11 @@ TEXT libc_select_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_select_trampoline_addr(SB), RODATA, $8 DATA ·libc_select_trampoline_addr(SB)/8, $libc_select_trampoline<>(SB) +TEXT libc_setattrlist_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_setattrlist(SB) +GLOBL ·libc_setattrlist_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setattrlist_trampoline_addr(SB)/8, $libc_setattrlist_trampoline<>(SB) + TEXT libc_setegid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setegid(SB) @@ -759,12 +764,6 @@ TEXT libc_setreuid_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_setreuid_trampoline_addr(SB), RODATA, $8 DATA ·libc_setreuid_trampoline_addr(SB)/8, $libc_setreuid_trampoline<>(SB) -TEXT libc_setrlimit_trampoline<>(SB),NOSPLIT,$0-0 - JMP libc_setrlimit(SB) - -GLOBL ·libc_setrlimit_trampoline_addr(SB), RODATA, $8 -DATA ·libc_setrlimit_trampoline_addr(SB)/8, $libc_setrlimit_trampoline<>(SB) - TEXT libc_setsid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setsid(SB) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go index 2fd4590bb7..51d6f3fb25 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go @@ -1992,6 +1992,31 @@ var libc_select_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Setattrlist(path string, attrlist *Attrlist, attrBuf []byte, options int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(attrBuf) > 0 { + _p1 = unsafe.Pointer(&attrBuf[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + _, _, e1 := syscall_syscall6(libc_setattrlist_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(attrlist)), uintptr(_p1), uintptr(len(attrBuf)), uintptr(options), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +var libc_setattrlist_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_setattrlist setattrlist "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Setegid(egid int) (err error) { _, _, e1 := syscall_syscall(libc_setegid_trampoline_addr, uintptr(egid), 0, 0) if e1 != 0 { @@ -2123,20 +2148,6 @@ var libc_setreuid_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Setrlimit(which int, lim *Rlimit) (err error) { - _, _, e1 := syscall_rawSyscall(libc_setrlimit_trampoline_addr, uintptr(which), uintptr(unsafe.Pointer(lim)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -var libc_setrlimit_trampoline_addr uintptr - -//go:cgo_import_dynamic libc_setrlimit setrlimit "/usr/lib/libSystem.B.dylib" - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Setsid() (pid int, err error) { r0, _, e1 := syscall_rawSyscall(libc_setsid_trampoline_addr, 0, 0, 0) pid = int(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s index efa5b4c987..c3b82c0379 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s @@ -705,6 +705,11 @@ TEXT libc_select_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_select_trampoline_addr(SB), RODATA, $8 DATA ·libc_select_trampoline_addr(SB)/8, $libc_select_trampoline<>(SB) +TEXT libc_setattrlist_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_setattrlist(SB) +GLOBL ·libc_setattrlist_trampoline_addr(SB), RODATA, $8 +DATA ·libc_setattrlist_trampoline_addr(SB)/8, $libc_setattrlist_trampoline<>(SB) + TEXT libc_setegid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setegid(SB) @@ -759,12 +764,6 @@ TEXT libc_setreuid_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_setreuid_trampoline_addr(SB), RODATA, $8 DATA ·libc_setreuid_trampoline_addr(SB)/8, $libc_setreuid_trampoline<>(SB) -TEXT libc_setrlimit_trampoline<>(SB),NOSPLIT,$0-0 - JMP libc_setrlimit(SB) - -GLOBL ·libc_setrlimit_trampoline_addr(SB), RODATA, $8 -DATA ·libc_setrlimit_trampoline_addr(SB)/8, $libc_setrlimit_trampoline<>(SB) - TEXT libc_setsid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setsid(SB) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go index 3b85134707..0eabac7ade 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go @@ -1410,16 +1410,6 @@ func Setresuid(ruid int, euid int, suid int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Setrlimit(which int, lim *Rlimit) (err error) { - _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Setsid() (pid int, err error) { r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0) pid = int(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go index 1129065624..ee313eb007 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go @@ -1645,16 +1645,6 @@ func Setresuid(ruid int, euid int, suid int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Setrlimit(which int, lim *Rlimit) (err error) { - _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Setsid() (pid int, err error) { r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0) pid = int(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go index 55f5abfe59..4c986e448e 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go @@ -1645,16 +1645,6 @@ func Setresuid(ruid int, euid int, suid int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Setrlimit(which int, lim *Rlimit) (err error) { - _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Setsid() (pid int, err error) { r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0) pid = int(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go index d39651c2b5..555216944a 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go @@ -1645,16 +1645,6 @@ func Setresuid(ruid int, euid int, suid int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Setrlimit(which int, lim *Rlimit) (err error) { - _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Setsid() (pid int, err error) { r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0) pid = int(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm64.go index ddb7408680..67a226fbf5 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm64.go @@ -1645,16 +1645,6 @@ func Setresuid(ruid int, euid int, suid int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Setrlimit(which int, lim *Rlimit) (err error) { - _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Setsid() (pid int, err error) { r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0) pid = int(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_riscv64.go b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_riscv64.go index 09a53a616c..f0b9ddaaa2 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_riscv64.go @@ -1645,16 +1645,6 @@ func Setresuid(ruid int, euid int, suid int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Setrlimit(which int, lim *Rlimit) (err error) { - _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Setsid() (pid int, err error) { r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0) pid = int(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux.go b/vendor/golang.org/x/sys/unix/zsyscall_linux.go index 430cb24de7..a07321bed9 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux.go @@ -1346,16 +1346,6 @@ func PivotRoot(newroot string, putold string) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) { - _, _, e1 := RawSyscall6(SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(newlimit)), uintptr(unsafe.Pointer(old)), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error) { _, _, e1 := Syscall6(SYS_PRCTL, uintptr(option), uintptr(arg2), uintptr(arg3), uintptr(arg4), uintptr(arg5), 0) if e1 != 0 { @@ -1366,7 +1356,7 @@ func Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) ( // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) { +func pselect6(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *sigset_argpack) (n int, err error) { r0, _, e1 := Syscall6(SYS_PSELECT6, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask))) n = int(r0) if e1 != 0 { @@ -1878,6 +1868,17 @@ func munmap(addr uintptr, length uintptr) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func mremap(oldaddr uintptr, oldlength uintptr, newlength uintptr, flags int, newaddr uintptr) (xaddr uintptr, err error) { + r0, _, e1 := Syscall6(SYS_MREMAP, uintptr(oldaddr), uintptr(oldlength), uintptr(newlength), uintptr(flags), uintptr(newaddr), 0) + xaddr = uintptr(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Madvise(b []byte, advice int) (err error) { var _p0 unsafe.Pointer if len(b) > 0 { @@ -2182,3 +2183,17 @@ func rtSigprocmask(how int, set *Sigset_t, oldset *Sigset_t, sigsetsize uintptr) } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func getresuid(ruid *_C_int, euid *_C_int, suid *_C_int) { + RawSyscallNoError(SYS_GETRESUID, uintptr(unsafe.Pointer(ruid)), uintptr(unsafe.Pointer(euid)), uintptr(unsafe.Pointer(suid))) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func getresgid(rgid *_C_int, egid *_C_int, sgid *_C_int) { + RawSyscallNoError(SYS_GETRESGID, uintptr(unsafe.Pointer(rgid)), uintptr(unsafe.Pointer(egid)), uintptr(unsafe.Pointer(sgid))) + return +} diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go index c81b0ad477..07b549cc25 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go @@ -411,16 +411,6 @@ func getrlimit(resource int, rlim *rlimit32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func setrlimit(resource int, rlim *rlimit32) (err error) { - _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func futimesat(dirfd int, path string, times *[2]Timeval) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go index 2206bce7f4..5f481bf83f 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go @@ -334,16 +334,6 @@ func setfsuid(uid int) (prev int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Setrlimit(resource int, rlim *Rlimit) (err error) { - _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Shutdown(fd int, how int) (err error) { _, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go index edf6b39f16..824cd52c7f 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go @@ -578,16 +578,6 @@ func getrlimit(resource int, rlim *rlimit32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func setrlimit(resource int, rlim *rlimit32) (err error) { - _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func armSyncFileRange(fd int, flags int, off int64, n int64) (err error) { _, _, e1 := Syscall6(SYS_ARM_SYNC_FILE_RANGE, uintptr(fd), uintptr(flags), uintptr(off), uintptr(off>>32), uintptr(n), uintptr(n>>32)) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go index 190609f214..e77aecfe98 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go @@ -289,16 +289,6 @@ func setfsuid(uid int) (prev int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func setrlimit(resource int, rlim *Rlimit) (err error) { - _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Shutdown(fd int, how int) (err error) { _, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go index 5f984cbb1c..961a3afb7b 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go @@ -644,16 +644,6 @@ func getrlimit(resource int, rlim *rlimit32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func setrlimit(resource int, rlim *rlimit32) (err error) { - _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Alarm(seconds uint) (remaining uint, err error) { r0, _, e1 := Syscall(SYS_ALARM, uintptr(seconds), 0, 0) remaining = uint(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go index 46fc380a40..ed05005e91 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go @@ -278,16 +278,6 @@ func setfsuid(uid int) (prev int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Setrlimit(resource int, rlim *Rlimit) (err error) { - _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Shutdown(fd int, how int) (err error) { _, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go index cbd0d4dadb..d365b718f3 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go @@ -278,16 +278,6 @@ func setfsuid(uid int) (prev int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Setrlimit(resource int, rlim *Rlimit) (err error) { - _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Shutdown(fd int, how int) (err error) { _, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go index 0c13d15f07..c3f1b8bbde 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go @@ -644,16 +644,6 @@ func getrlimit(resource int, rlim *rlimit32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func setrlimit(resource int, rlim *rlimit32) (err error) { - _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Alarm(seconds uint) (remaining uint, err error) { r0, _, e1 := Syscall(SYS_ALARM, uintptr(seconds), 0, 0) remaining = uint(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc.go index e01432aed5..a6574cf98b 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc.go @@ -624,16 +624,6 @@ func getrlimit(resource int, rlim *rlimit32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func setrlimit(resource int, rlim *rlimit32) (err error) { - _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func syncFileRange2(fd int, flags int, off int64, n int64) (err error) { _, _, e1 := Syscall6(SYS_SYNC_FILE_RANGE2, uintptr(fd), uintptr(flags), uintptr(off>>32), uintptr(off), uintptr(n>>32), uintptr(n)) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go index 13c7ee7baf..f40990264f 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go @@ -349,16 +349,6 @@ func setfsuid(uid int) (prev int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Setrlimit(resource int, rlim *Rlimit) (err error) { - _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Shutdown(fd int, how int) (err error) { _, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go index 02d0c0fd61..9dfcc29974 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go @@ -349,16 +349,6 @@ func setfsuid(uid int) (prev int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Setrlimit(resource int, rlim *Rlimit) (err error) { - _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Shutdown(fd int, how int) (err error) { _, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go index 9fee3b1d23..0ab4f2ed72 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go @@ -269,16 +269,6 @@ func setfsuid(uid int) (prev int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Setrlimit(resource int, rlim *Rlimit) (err error) { - _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Shutdown(fd int, how int) (err error) { _, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0) if e1 != 0 { @@ -541,3 +531,19 @@ func kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, f } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func riscvHWProbe(pairs []RISCVHWProbePairs, cpuCount uintptr, cpus *CPUSet, flags uint) (err error) { + var _p0 unsafe.Pointer + if len(pairs) > 0 { + _p0 = unsafe.Pointer(&pairs[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, e1 := Syscall6(SYS_RISCV_HWPROBE, uintptr(_p0), uintptr(len(pairs)), uintptr(cpuCount), uintptr(unsafe.Pointer(cpus)), uintptr(flags), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go index 647bbfecd6..6cde32237d 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go @@ -319,16 +319,6 @@ func setfsuid(uid int) (prev int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Setrlimit(resource int, rlim *Rlimit) (err error) { - _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) { r0, _, e1 := Syscall6(SYS_SPLICE, uintptr(rfd), uintptr(unsafe.Pointer(roff)), uintptr(wfd), uintptr(unsafe.Pointer(woff)), uintptr(len), uintptr(flags)) n = int64(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go index ada057f891..5253d65bf1 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go @@ -329,16 +329,6 @@ func setfsuid(uid int) (prev int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Setrlimit(resource int, rlim *Rlimit) (err error) { - _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Shutdown(fd int, how int) (err error) { _, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go index 8e1d9c8f66..35f499b32a 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go @@ -1607,16 +1607,6 @@ func Setreuid(ruid int, euid int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Setrlimit(which int, lim *Rlimit) (err error) { - _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Setsid() (pid int, err error) { r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0) pid = int(r0) @@ -1868,3 +1858,14 @@ func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func mremapNetBSD(oldp uintptr, oldsize uintptr, newp uintptr, newsize uintptr, flags int) (xaddr uintptr, err error) { + r0, _, e1 := Syscall6(SYS_MREMAP, uintptr(oldp), uintptr(oldsize), uintptr(newp), uintptr(newsize), uintptr(flags), 0) + xaddr = uintptr(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go index 21c6950400..3cda65b0da 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go @@ -1607,16 +1607,6 @@ func Setreuid(ruid int, euid int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Setrlimit(which int, lim *Rlimit) (err error) { - _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Setsid() (pid int, err error) { r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0) pid = int(r0) @@ -1868,3 +1858,14 @@ func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func mremapNetBSD(oldp uintptr, oldsize uintptr, newp uintptr, newsize uintptr, flags int) (xaddr uintptr, err error) { + r0, _, e1 := Syscall6(SYS_MREMAP, uintptr(oldp), uintptr(oldsize), uintptr(newp), uintptr(newsize), uintptr(flags), 0) + xaddr = uintptr(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go index 298168f90a..1e1fea902b 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go @@ -1607,16 +1607,6 @@ func Setreuid(ruid int, euid int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Setrlimit(which int, lim *Rlimit) (err error) { - _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Setsid() (pid int, err error) { r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0) pid = int(r0) @@ -1868,3 +1858,14 @@ func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func mremapNetBSD(oldp uintptr, oldsize uintptr, newp uintptr, newsize uintptr, flags int) (xaddr uintptr, err error) { + r0, _, e1 := Syscall6(SYS_MREMAP, uintptr(oldp), uintptr(oldsize), uintptr(newp), uintptr(newsize), uintptr(flags), 0) + xaddr = uintptr(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm64.go index 68b8bd492f..3b77da1107 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm64.go @@ -1607,16 +1607,6 @@ func Setreuid(ruid int, euid int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Setrlimit(which int, lim *Rlimit) (err error) { - _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Setsid() (pid int, err error) { r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0) pid = int(r0) @@ -1868,3 +1858,14 @@ func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func mremapNetBSD(oldp uintptr, oldsize uintptr, newp uintptr, newsize uintptr, flags int) (xaddr uintptr, err error) { + r0, _, e1 := Syscall6(SYS_MREMAP, uintptr(oldp), uintptr(oldsize), uintptr(newp), uintptr(newsize), uintptr(flags), 0) + xaddr = uintptr(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go index 0b0f910e1a..9ab9abf721 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go @@ -519,6 +519,28 @@ var libc_getcwd_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func getresuid(ruid *_C_int, euid *_C_int, suid *_C_int) { + syscall_rawSyscall(libc_getresuid_trampoline_addr, uintptr(unsafe.Pointer(ruid)), uintptr(unsafe.Pointer(euid)), uintptr(unsafe.Pointer(suid))) + return +} + +var libc_getresuid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getresuid getresuid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func getresgid(rgid *_C_int, egid *_C_int, sgid *_C_int) { + syscall_rawSyscall(libc_getresgid_trampoline_addr, uintptr(unsafe.Pointer(rgid)), uintptr(unsafe.Pointer(egid)), uintptr(unsafe.Pointer(sgid))) + return +} + +var libc_getresgid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getresgid getresgid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func ioctl(fd int, req uint, arg uintptr) (err error) { _, _, e1 := syscall_syscall(libc_ioctl_trampoline_addr, uintptr(fd), uintptr(req), uintptr(arg)) if e1 != 0 { @@ -1894,20 +1916,6 @@ var libc_setresuid_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Setrlimit(which int, lim *Rlimit) (err error) { - _, _, e1 := syscall_rawSyscall(libc_setrlimit_trampoline_addr, uintptr(which), uintptr(unsafe.Pointer(lim)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -var libc_setrlimit_trampoline_addr uintptr - -//go:cgo_import_dynamic libc_setrlimit setrlimit "libc.so" - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Setrtable(rtable int) (err error) { _, _, e1 := syscall_rawSyscall(libc_setrtable_trampoline_addr, uintptr(rtable), 0, 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.s b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.s index 087444250c..3dcacd30d7 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.s @@ -158,6 +158,16 @@ TEXT libc_getcwd_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_getcwd_trampoline_addr(SB), RODATA, $4 DATA ·libc_getcwd_trampoline_addr(SB)/4, $libc_getcwd_trampoline<>(SB) +TEXT libc_getresuid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getresuid(SB) +GLOBL ·libc_getresuid_trampoline_addr(SB), RODATA, $4 +DATA ·libc_getresuid_trampoline_addr(SB)/4, $libc_getresuid_trampoline<>(SB) + +TEXT libc_getresgid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getresgid(SB) +GLOBL ·libc_getresgid_trampoline_addr(SB), RODATA, $4 +DATA ·libc_getresgid_trampoline_addr(SB)/4, $libc_getresgid_trampoline<>(SB) + TEXT libc_ioctl_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_ioctl(SB) GLOBL ·libc_ioctl_trampoline_addr(SB), RODATA, $4 @@ -573,11 +583,6 @@ TEXT libc_setresuid_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_setresuid_trampoline_addr(SB), RODATA, $4 DATA ·libc_setresuid_trampoline_addr(SB)/4, $libc_setresuid_trampoline<>(SB) -TEXT libc_setrlimit_trampoline<>(SB),NOSPLIT,$0-0 - JMP libc_setrlimit(SB) -GLOBL ·libc_setrlimit_trampoline_addr(SB), RODATA, $4 -DATA ·libc_setrlimit_trampoline_addr(SB)/4, $libc_setrlimit_trampoline<>(SB) - TEXT libc_setrtable_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setrtable(SB) GLOBL ·libc_setrtable_trampoline_addr(SB), RODATA, $4 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go index 48ff5de75b..915761eab7 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go @@ -519,6 +519,28 @@ var libc_getcwd_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func getresuid(ruid *_C_int, euid *_C_int, suid *_C_int) { + syscall_rawSyscall(libc_getresuid_trampoline_addr, uintptr(unsafe.Pointer(ruid)), uintptr(unsafe.Pointer(euid)), uintptr(unsafe.Pointer(suid))) + return +} + +var libc_getresuid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getresuid getresuid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func getresgid(rgid *_C_int, egid *_C_int, sgid *_C_int) { + syscall_rawSyscall(libc_getresgid_trampoline_addr, uintptr(unsafe.Pointer(rgid)), uintptr(unsafe.Pointer(egid)), uintptr(unsafe.Pointer(sgid))) + return +} + +var libc_getresgid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getresgid getresgid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func ioctl(fd int, req uint, arg uintptr) (err error) { _, _, e1 := syscall_syscall(libc_ioctl_trampoline_addr, uintptr(fd), uintptr(req), uintptr(arg)) if e1 != 0 { @@ -527,6 +549,12 @@ func ioctl(fd int, req uint, arg uintptr) (err error) { return } +var libc_ioctl_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_ioctl ioctl "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { _, _, e1 := syscall_syscall(libc_ioctl_trampoline_addr, uintptr(fd), uintptr(req), uintptr(arg)) if e1 != 0 { @@ -535,10 +563,6 @@ func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { return } -var libc_ioctl_trampoline_addr uintptr - -//go:cgo_import_dynamic libc_ioctl ioctl "libc.so" - // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) { @@ -1894,20 +1918,6 @@ var libc_setresuid_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Setrlimit(which int, lim *Rlimit) (err error) { - _, _, e1 := syscall_rawSyscall(libc_setrlimit_trampoline_addr, uintptr(which), uintptr(unsafe.Pointer(lim)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -var libc_setrlimit_trampoline_addr uintptr - -//go:cgo_import_dynamic libc_setrlimit setrlimit "libc.so" - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Setrtable(rtable int) (err error) { _, _, e1 := syscall_rawSyscall(libc_setrtable_trampoline_addr, uintptr(rtable), 0, 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.s b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.s index 5782cd1084..2763620b01 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.s @@ -158,6 +158,16 @@ TEXT libc_getcwd_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_getcwd_trampoline_addr(SB), RODATA, $8 DATA ·libc_getcwd_trampoline_addr(SB)/8, $libc_getcwd_trampoline<>(SB) +TEXT libc_getresuid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getresuid(SB) +GLOBL ·libc_getresuid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getresuid_trampoline_addr(SB)/8, $libc_getresuid_trampoline<>(SB) + +TEXT libc_getresgid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getresgid(SB) +GLOBL ·libc_getresgid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getresgid_trampoline_addr(SB)/8, $libc_getresgid_trampoline<>(SB) + TEXT libc_ioctl_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_ioctl(SB) GLOBL ·libc_ioctl_trampoline_addr(SB), RODATA, $8 @@ -573,11 +583,6 @@ TEXT libc_setresuid_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_setresuid_trampoline_addr(SB), RODATA, $8 DATA ·libc_setresuid_trampoline_addr(SB)/8, $libc_setresuid_trampoline<>(SB) -TEXT libc_setrlimit_trampoline<>(SB),NOSPLIT,$0-0 - JMP libc_setrlimit(SB) -GLOBL ·libc_setrlimit_trampoline_addr(SB), RODATA, $8 -DATA ·libc_setrlimit_trampoline_addr(SB)/8, $libc_setrlimit_trampoline<>(SB) - TEXT libc_setrtable_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setrtable(SB) GLOBL ·libc_setrtable_trampoline_addr(SB), RODATA, $8 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go index 2452a641da..8e87fdf153 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go @@ -519,6 +519,28 @@ var libc_getcwd_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func getresuid(ruid *_C_int, euid *_C_int, suid *_C_int) { + syscall_rawSyscall(libc_getresuid_trampoline_addr, uintptr(unsafe.Pointer(ruid)), uintptr(unsafe.Pointer(euid)), uintptr(unsafe.Pointer(suid))) + return +} + +var libc_getresuid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getresuid getresuid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func getresgid(rgid *_C_int, egid *_C_int, sgid *_C_int) { + syscall_rawSyscall(libc_getresgid_trampoline_addr, uintptr(unsafe.Pointer(rgid)), uintptr(unsafe.Pointer(egid)), uintptr(unsafe.Pointer(sgid))) + return +} + +var libc_getresgid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getresgid getresgid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func ioctl(fd int, req uint, arg uintptr) (err error) { _, _, e1 := syscall_syscall(libc_ioctl_trampoline_addr, uintptr(fd), uintptr(req), uintptr(arg)) if e1 != 0 { @@ -1894,20 +1916,6 @@ var libc_setresuid_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Setrlimit(which int, lim *Rlimit) (err error) { - _, _, e1 := syscall_rawSyscall(libc_setrlimit_trampoline_addr, uintptr(which), uintptr(unsafe.Pointer(lim)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -var libc_setrlimit_trampoline_addr uintptr - -//go:cgo_import_dynamic libc_setrlimit setrlimit "libc.so" - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Setrtable(rtable int) (err error) { _, _, e1 := syscall_rawSyscall(libc_setrtable_trampoline_addr, uintptr(rtable), 0, 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.s b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.s index cf310420c9..c922314048 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.s @@ -158,6 +158,16 @@ TEXT libc_getcwd_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_getcwd_trampoline_addr(SB), RODATA, $4 DATA ·libc_getcwd_trampoline_addr(SB)/4, $libc_getcwd_trampoline<>(SB) +TEXT libc_getresuid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getresuid(SB) +GLOBL ·libc_getresuid_trampoline_addr(SB), RODATA, $4 +DATA ·libc_getresuid_trampoline_addr(SB)/4, $libc_getresuid_trampoline<>(SB) + +TEXT libc_getresgid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getresgid(SB) +GLOBL ·libc_getresgid_trampoline_addr(SB), RODATA, $4 +DATA ·libc_getresgid_trampoline_addr(SB)/4, $libc_getresgid_trampoline<>(SB) + TEXT libc_ioctl_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_ioctl(SB) GLOBL ·libc_ioctl_trampoline_addr(SB), RODATA, $4 @@ -573,11 +583,6 @@ TEXT libc_setresuid_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_setresuid_trampoline_addr(SB), RODATA, $4 DATA ·libc_setresuid_trampoline_addr(SB)/4, $libc_setresuid_trampoline<>(SB) -TEXT libc_setrlimit_trampoline<>(SB),NOSPLIT,$0-0 - JMP libc_setrlimit(SB) -GLOBL ·libc_setrlimit_trampoline_addr(SB), RODATA, $4 -DATA ·libc_setrlimit_trampoline_addr(SB)/4, $libc_setrlimit_trampoline<>(SB) - TEXT libc_setrtable_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setrtable(SB) GLOBL ·libc_setrtable_trampoline_addr(SB), RODATA, $4 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go index 5e35600a60..12a7a2160e 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go @@ -519,6 +519,28 @@ var libc_getcwd_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func getresuid(ruid *_C_int, euid *_C_int, suid *_C_int) { + syscall_rawSyscall(libc_getresuid_trampoline_addr, uintptr(unsafe.Pointer(ruid)), uintptr(unsafe.Pointer(euid)), uintptr(unsafe.Pointer(suid))) + return +} + +var libc_getresuid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getresuid getresuid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func getresgid(rgid *_C_int, egid *_C_int, sgid *_C_int) { + syscall_rawSyscall(libc_getresgid_trampoline_addr, uintptr(unsafe.Pointer(rgid)), uintptr(unsafe.Pointer(egid)), uintptr(unsafe.Pointer(sgid))) + return +} + +var libc_getresgid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getresgid getresgid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func ioctl(fd int, req uint, arg uintptr) (err error) { _, _, e1 := syscall_syscall(libc_ioctl_trampoline_addr, uintptr(fd), uintptr(req), uintptr(arg)) if e1 != 0 { @@ -1894,20 +1916,6 @@ var libc_setresuid_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Setrlimit(which int, lim *Rlimit) (err error) { - _, _, e1 := syscall_rawSyscall(libc_setrlimit_trampoline_addr, uintptr(which), uintptr(unsafe.Pointer(lim)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -var libc_setrlimit_trampoline_addr uintptr - -//go:cgo_import_dynamic libc_setrlimit setrlimit "libc.so" - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Setrtable(rtable int) (err error) { _, _, e1 := syscall_rawSyscall(libc_setrtable_trampoline_addr, uintptr(rtable), 0, 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.s b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.s index 484bb42e0a..a6bc32c922 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.s @@ -158,6 +158,16 @@ TEXT libc_getcwd_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_getcwd_trampoline_addr(SB), RODATA, $8 DATA ·libc_getcwd_trampoline_addr(SB)/8, $libc_getcwd_trampoline<>(SB) +TEXT libc_getresuid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getresuid(SB) +GLOBL ·libc_getresuid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getresuid_trampoline_addr(SB)/8, $libc_getresuid_trampoline<>(SB) + +TEXT libc_getresgid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getresgid(SB) +GLOBL ·libc_getresgid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getresgid_trampoline_addr(SB)/8, $libc_getresgid_trampoline<>(SB) + TEXT libc_ioctl_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_ioctl(SB) GLOBL ·libc_ioctl_trampoline_addr(SB), RODATA, $8 @@ -573,11 +583,6 @@ TEXT libc_setresuid_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_setresuid_trampoline_addr(SB), RODATA, $8 DATA ·libc_setresuid_trampoline_addr(SB)/8, $libc_setresuid_trampoline<>(SB) -TEXT libc_setrlimit_trampoline<>(SB),NOSPLIT,$0-0 - JMP libc_setrlimit(SB) -GLOBL ·libc_setrlimit_trampoline_addr(SB), RODATA, $8 -DATA ·libc_setrlimit_trampoline_addr(SB)/8, $libc_setrlimit_trampoline<>(SB) - TEXT libc_setrtable_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setrtable(SB) GLOBL ·libc_setrtable_trampoline_addr(SB), RODATA, $8 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go index b04cef1a19..b19e8aa031 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go @@ -519,6 +519,28 @@ var libc_getcwd_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func getresuid(ruid *_C_int, euid *_C_int, suid *_C_int) { + syscall_rawSyscall(libc_getresuid_trampoline_addr, uintptr(unsafe.Pointer(ruid)), uintptr(unsafe.Pointer(euid)), uintptr(unsafe.Pointer(suid))) + return +} + +var libc_getresuid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getresuid getresuid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func getresgid(rgid *_C_int, egid *_C_int, sgid *_C_int) { + syscall_rawSyscall(libc_getresgid_trampoline_addr, uintptr(unsafe.Pointer(rgid)), uintptr(unsafe.Pointer(egid)), uintptr(unsafe.Pointer(sgid))) + return +} + +var libc_getresgid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getresgid getresgid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func ioctl(fd int, req uint, arg uintptr) (err error) { _, _, e1 := syscall_syscall(libc_ioctl_trampoline_addr, uintptr(fd), uintptr(req), uintptr(arg)) if e1 != 0 { @@ -1894,20 +1916,6 @@ var libc_setresuid_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Setrlimit(which int, lim *Rlimit) (err error) { - _, _, e1 := syscall_rawSyscall(libc_setrlimit_trampoline_addr, uintptr(which), uintptr(unsafe.Pointer(lim)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -var libc_setrlimit_trampoline_addr uintptr - -//go:cgo_import_dynamic libc_setrlimit setrlimit "libc.so" - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Setrtable(rtable int) (err error) { _, _, e1 := syscall_rawSyscall(libc_setrtable_trampoline_addr, uintptr(rtable), 0, 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.s b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.s index 55af27263a..b4e7bceabf 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.s @@ -158,6 +158,16 @@ TEXT libc_getcwd_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_getcwd_trampoline_addr(SB), RODATA, $8 DATA ·libc_getcwd_trampoline_addr(SB)/8, $libc_getcwd_trampoline<>(SB) +TEXT libc_getresuid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getresuid(SB) +GLOBL ·libc_getresuid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getresuid_trampoline_addr(SB)/8, $libc_getresuid_trampoline<>(SB) + +TEXT libc_getresgid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getresgid(SB) +GLOBL ·libc_getresgid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getresgid_trampoline_addr(SB)/8, $libc_getresgid_trampoline<>(SB) + TEXT libc_ioctl_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_ioctl(SB) GLOBL ·libc_ioctl_trampoline_addr(SB), RODATA, $8 @@ -573,11 +583,6 @@ TEXT libc_setresuid_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_setresuid_trampoline_addr(SB), RODATA, $8 DATA ·libc_setresuid_trampoline_addr(SB)/8, $libc_setresuid_trampoline<>(SB) -TEXT libc_setrlimit_trampoline<>(SB),NOSPLIT,$0-0 - JMP libc_setrlimit(SB) -GLOBL ·libc_setrlimit_trampoline_addr(SB), RODATA, $8 -DATA ·libc_setrlimit_trampoline_addr(SB)/8, $libc_setrlimit_trampoline<>(SB) - TEXT libc_setrtable_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setrtable(SB) GLOBL ·libc_setrtable_trampoline_addr(SB), RODATA, $8 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go index 47a07ee0c2..fb99594c93 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go @@ -519,6 +519,28 @@ var libc_getcwd_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func getresuid(ruid *_C_int, euid *_C_int, suid *_C_int) { + syscall_rawSyscall(libc_getresuid_trampoline_addr, uintptr(unsafe.Pointer(ruid)), uintptr(unsafe.Pointer(euid)), uintptr(unsafe.Pointer(suid))) + return +} + +var libc_getresuid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getresuid getresuid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func getresgid(rgid *_C_int, egid *_C_int, sgid *_C_int) { + syscall_rawSyscall(libc_getresgid_trampoline_addr, uintptr(unsafe.Pointer(rgid)), uintptr(unsafe.Pointer(egid)), uintptr(unsafe.Pointer(sgid))) + return +} + +var libc_getresgid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getresgid getresgid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func ioctl(fd int, req uint, arg uintptr) (err error) { _, _, e1 := syscall_syscall(libc_ioctl_trampoline_addr, uintptr(fd), uintptr(req), uintptr(arg)) if e1 != 0 { @@ -1894,20 +1916,6 @@ var libc_setresuid_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Setrlimit(which int, lim *Rlimit) (err error) { - _, _, e1 := syscall_rawSyscall(libc_setrlimit_trampoline_addr, uintptr(which), uintptr(unsafe.Pointer(lim)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -var libc_setrlimit_trampoline_addr uintptr - -//go:cgo_import_dynamic libc_setrlimit setrlimit "libc.so" - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Setrtable(rtable int) (err error) { _, _, e1 := syscall_rawSyscall(libc_setrtable_trampoline_addr, uintptr(rtable), 0, 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.s b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.s index 4028255b0d..ca3f766009 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.s @@ -189,6 +189,18 @@ TEXT libc_getcwd_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_getcwd_trampoline_addr(SB), RODATA, $8 DATA ·libc_getcwd_trampoline_addr(SB)/8, $libc_getcwd_trampoline<>(SB) +TEXT libc_getresuid_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_getresuid(SB) + RET +GLOBL ·libc_getresuid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getresuid_trampoline_addr(SB)/8, $libc_getresuid_trampoline<>(SB) + +TEXT libc_getresgid_trampoline<>(SB),NOSPLIT,$0-0 + CALL libc_getresgid(SB) + RET +GLOBL ·libc_getresgid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getresgid_trampoline_addr(SB)/8, $libc_getresgid_trampoline<>(SB) + TEXT libc_ioctl_trampoline<>(SB),NOSPLIT,$0-0 CALL libc_ioctl(SB) RET @@ -687,12 +699,6 @@ TEXT libc_setresuid_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_setresuid_trampoline_addr(SB), RODATA, $8 DATA ·libc_setresuid_trampoline_addr(SB)/8, $libc_setresuid_trampoline<>(SB) -TEXT libc_setrlimit_trampoline<>(SB),NOSPLIT,$0-0 - CALL libc_setrlimit(SB) - RET -GLOBL ·libc_setrlimit_trampoline_addr(SB), RODATA, $8 -DATA ·libc_setrlimit_trampoline_addr(SB)/8, $libc_setrlimit_trampoline<>(SB) - TEXT libc_setrtable_trampoline<>(SB),NOSPLIT,$0-0 CALL libc_setrtable(SB) RET diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go index 573378fdb9..32cbbbc52b 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go @@ -519,6 +519,28 @@ var libc_getcwd_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func getresuid(ruid *_C_int, euid *_C_int, suid *_C_int) { + syscall_rawSyscall(libc_getresuid_trampoline_addr, uintptr(unsafe.Pointer(ruid)), uintptr(unsafe.Pointer(euid)), uintptr(unsafe.Pointer(suid))) + return +} + +var libc_getresuid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getresuid getresuid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func getresgid(rgid *_C_int, egid *_C_int, sgid *_C_int) { + syscall_rawSyscall(libc_getresgid_trampoline_addr, uintptr(unsafe.Pointer(rgid)), uintptr(unsafe.Pointer(egid)), uintptr(unsafe.Pointer(sgid))) + return +} + +var libc_getresgid_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_getresgid getresgid "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func ioctl(fd int, req uint, arg uintptr) (err error) { _, _, e1 := syscall_syscall(libc_ioctl_trampoline_addr, uintptr(fd), uintptr(req), uintptr(arg)) if e1 != 0 { @@ -1894,20 +1916,6 @@ var libc_setresuid_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Setrlimit(which int, lim *Rlimit) (err error) { - _, _, e1 := syscall_rawSyscall(libc_setrlimit_trampoline_addr, uintptr(which), uintptr(unsafe.Pointer(lim)), 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -var libc_setrlimit_trampoline_addr uintptr - -//go:cgo_import_dynamic libc_setrlimit setrlimit "libc.so" - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Setrtable(rtable int) (err error) { _, _, e1 := syscall_rawSyscall(libc_setrtable_trampoline_addr, uintptr(rtable), 0, 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.s b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.s index e1fbd4dfa8..477a7d5b21 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.s @@ -158,6 +158,16 @@ TEXT libc_getcwd_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_getcwd_trampoline_addr(SB), RODATA, $8 DATA ·libc_getcwd_trampoline_addr(SB)/8, $libc_getcwd_trampoline<>(SB) +TEXT libc_getresuid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getresuid(SB) +GLOBL ·libc_getresuid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getresuid_trampoline_addr(SB)/8, $libc_getresuid_trampoline<>(SB) + +TEXT libc_getresgid_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_getresgid(SB) +GLOBL ·libc_getresgid_trampoline_addr(SB), RODATA, $8 +DATA ·libc_getresgid_trampoline_addr(SB)/8, $libc_getresgid_trampoline<>(SB) + TEXT libc_ioctl_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_ioctl(SB) GLOBL ·libc_ioctl_trampoline_addr(SB), RODATA, $8 @@ -573,11 +583,6 @@ TEXT libc_setresuid_trampoline<>(SB),NOSPLIT,$0-0 GLOBL ·libc_setresuid_trampoline_addr(SB), RODATA, $8 DATA ·libc_setresuid_trampoline_addr(SB)/8, $libc_setresuid_trampoline<>(SB) -TEXT libc_setrlimit_trampoline<>(SB),NOSPLIT,$0-0 - JMP libc_setrlimit(SB) -GLOBL ·libc_setrlimit_trampoline_addr(SB), RODATA, $8 -DATA ·libc_setrlimit_trampoline_addr(SB)/8, $libc_setrlimit_trampoline<>(SB) - TEXT libc_setrtable_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setrtable(SB) GLOBL ·libc_setrtable_trampoline_addr(SB), RODATA, $8 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go index 4873a1e5d3..609d1c598a 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go @@ -110,7 +110,6 @@ import ( //go:cgo_import_dynamic libc_setpriority setpriority "libc.so" //go:cgo_import_dynamic libc_setregid setregid "libc.so" //go:cgo_import_dynamic libc_setreuid setreuid "libc.so" -//go:cgo_import_dynamic libc_setrlimit setrlimit "libc.so" //go:cgo_import_dynamic libc_setsid setsid "libc.so" //go:cgo_import_dynamic libc_setuid setuid "libc.so" //go:cgo_import_dynamic libc_shutdown shutdown "libsocket.so" @@ -250,7 +249,6 @@ import ( //go:linkname procSetpriority libc_setpriority //go:linkname procSetregid libc_setregid //go:linkname procSetreuid libc_setreuid -//go:linkname procSetrlimit libc_setrlimit //go:linkname procSetsid libc_setsid //go:linkname procSetuid libc_setuid //go:linkname procshutdown libc_shutdown @@ -391,7 +389,6 @@ var ( procSetpriority, procSetregid, procSetreuid, - procSetrlimit, procSetsid, procSetuid, procshutdown, @@ -646,7 +643,7 @@ func __minor(version int, dev uint64) (val uint) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func ioctlRet(fd int, req uint, arg uintptr) (ret int, err error) { +func ioctlRet(fd int, req int, arg uintptr) (ret int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procioctl)), 3, uintptr(fd), uintptr(req), uintptr(arg), 0, 0, 0) ret = int(r0) if e1 != 0 { @@ -657,7 +654,7 @@ func ioctlRet(fd int, req uint, arg uintptr) (ret int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func ioctlPtrRet(fd int, req uint, arg unsafe.Pointer) (ret int, err error) { +func ioctlPtrRet(fd int, req int, arg unsafe.Pointer) (ret int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procioctl)), 3, uintptr(fd), uintptr(req), uintptr(arg), 0, 0, 0) ret = int(r0) if e1 != 0 { @@ -1650,16 +1647,6 @@ func Setreuid(ruid int, euid int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Setrlimit(which int, lim *Rlimit) (err error) { - _, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&procSetrlimit)), 2, uintptr(which), uintptr(unsafe.Pointer(lim)), 0, 0, 0, 0) - if e1 != 0 { - err = e1 - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Setsid() (pid int, err error) { r0, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&procSetsid)), 0, 0, 0, 0, 0, 0, 0) pid = int(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_zos_s390x.go b/vendor/golang.org/x/sys/unix/zsyscall_zos_s390x.go index 07bfe2ef9a..c31681743c 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_zos_s390x.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_zos_s390x.go @@ -257,7 +257,7 @@ func munmap(addr uintptr, length uintptr) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func ioctl(fd int, req uint, arg uintptr) (err error) { +func ioctl(fd int, req int, arg uintptr) (err error) { _, _, e1 := syscall_syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) if e1 != 0 { err = errnoErr(e1) @@ -267,7 +267,7 @@ func ioctl(fd int, req uint, arg uintptr) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { +func ioctlPtr(fd int, req int, arg unsafe.Pointer) (err error) { _, _, e1 := syscall_syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg)) if e1 != 0 { err = errnoErr(e1) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go index 3e594a8c09..ef285c567b 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go @@ -251,6 +251,8 @@ const ( SYS_ACCEPT4 = 242 SYS_RECVMMSG = 243 SYS_ARCH_SPECIFIC_SYSCALL = 244 + SYS_RISCV_HWPROBE = 258 + SYS_RISCV_FLUSH_ICACHE = 259 SYS_WAIT4 = 260 SYS_PRLIMIT64 = 261 SYS_FANOTIFY_INIT = 262 diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go index 7ea465204b..e6ed7d637d 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go @@ -372,6 +372,7 @@ const ( SYS_LANDLOCK_CREATE_RULESET = 444 SYS_LANDLOCK_ADD_RULE = 445 SYS_LANDLOCK_RESTRICT_SELF = 446 + SYS_MEMFD_SECRET = 447 SYS_PROCESS_MRELEASE = 448 SYS_FUTEX_WAITV = 449 SYS_SET_MEMPOLICY_HOME_NODE = 450 diff --git a/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go index e2a64f0991..690cefc3d0 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go @@ -151,6 +151,16 @@ type Dirent struct { _ [3]byte } +type Attrlist struct { + Bitmapcount uint16 + Reserved uint16 + Commonattr uint32 + Volattr uint32 + Dirattr uint32 + Fileattr uint32 + Forkattr uint32 +} + const ( PathMax = 0x400 ) @@ -610,6 +620,7 @@ const ( AT_REMOVEDIR = 0x80 AT_SYMLINK_FOLLOW = 0x40 AT_SYMLINK_NOFOLLOW = 0x20 + AT_EACCESS = 0x10 ) type PollFd struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go index 34aa775219..5bffc10eac 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go @@ -151,6 +151,16 @@ type Dirent struct { _ [3]byte } +type Attrlist struct { + Bitmapcount uint16 + Reserved uint16 + Commonattr uint32 + Volattr uint32 + Dirattr uint32 + Fileattr uint32 + Forkattr uint32 +} + const ( PathMax = 0x400 ) @@ -610,6 +620,7 @@ const ( AT_REMOVEDIR = 0x80 AT_SYMLINK_FOLLOW = 0x40 AT_SYMLINK_NOFOLLOW = 0x20 + AT_EACCESS = 0x10 ) type PollFd struct { diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux.go b/vendor/golang.org/x/sys/unix/ztypes_linux.go index ca84727cfe..26ef52aafc 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux.go @@ -866,6 +866,11 @@ const ( POLLNVAL = 0x20 ) +type sigset_argpack struct { + ss *Sigset_t + ssLen uintptr +} + type SignalfdSiginfo struct { Signo uint32 Errno int32 @@ -1538,6 +1543,10 @@ const ( IFLA_GRO_MAX_SIZE = 0x3a IFLA_TSO_MAX_SIZE = 0x3b IFLA_TSO_MAX_SEGS = 0x3c + IFLA_ALLMULTI = 0x3d + IFLA_DEVLINK_PORT = 0x3e + IFLA_GSO_IPV4_MAX_SIZE = 0x3f + IFLA_GRO_IPV4_MAX_SIZE = 0x40 IFLA_PROTO_DOWN_REASON_UNSPEC = 0x0 IFLA_PROTO_DOWN_REASON_MASK = 0x1 IFLA_PROTO_DOWN_REASON_VALUE = 0x2 @@ -1968,7 +1977,7 @@ const ( NFT_MSG_GETFLOWTABLE = 0x17 NFT_MSG_DELFLOWTABLE = 0x18 NFT_MSG_GETRULE_RESET = 0x19 - NFT_MSG_MAX = 0x1a + NFT_MSG_MAX = 0x21 NFTA_LIST_UNSPEC = 0x0 NFTA_LIST_ELEM = 0x1 NFTA_HOOK_UNSPEC = 0x0 @@ -2555,6 +2564,11 @@ const ( BPF_REG_8 = 0x8 BPF_REG_9 = 0x9 BPF_REG_10 = 0xa + BPF_CGROUP_ITER_ORDER_UNSPEC = 0x0 + BPF_CGROUP_ITER_SELF_ONLY = 0x1 + BPF_CGROUP_ITER_DESCENDANTS_PRE = 0x2 + BPF_CGROUP_ITER_DESCENDANTS_POST = 0x3 + BPF_CGROUP_ITER_ANCESTORS_UP = 0x4 BPF_MAP_CREATE = 0x0 BPF_MAP_LOOKUP_ELEM = 0x1 BPF_MAP_UPDATE_ELEM = 0x2 @@ -2566,6 +2580,7 @@ const ( BPF_PROG_ATTACH = 0x8 BPF_PROG_DETACH = 0x9 BPF_PROG_TEST_RUN = 0xa + BPF_PROG_RUN = 0xa BPF_PROG_GET_NEXT_ID = 0xb BPF_MAP_GET_NEXT_ID = 0xc BPF_PROG_GET_FD_BY_ID = 0xd @@ -2610,6 +2625,7 @@ const ( BPF_MAP_TYPE_CPUMAP = 0x10 BPF_MAP_TYPE_XSKMAP = 0x11 BPF_MAP_TYPE_SOCKHASH = 0x12 + BPF_MAP_TYPE_CGROUP_STORAGE_DEPRECATED = 0x13 BPF_MAP_TYPE_CGROUP_STORAGE = 0x13 BPF_MAP_TYPE_REUSEPORT_SOCKARRAY = 0x14 BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE = 0x15 @@ -2620,6 +2636,10 @@ const ( BPF_MAP_TYPE_STRUCT_OPS = 0x1a BPF_MAP_TYPE_RINGBUF = 0x1b BPF_MAP_TYPE_INODE_STORAGE = 0x1c + BPF_MAP_TYPE_TASK_STORAGE = 0x1d + BPF_MAP_TYPE_BLOOM_FILTER = 0x1e + BPF_MAP_TYPE_USER_RINGBUF = 0x1f + BPF_MAP_TYPE_CGRP_STORAGE = 0x20 BPF_PROG_TYPE_UNSPEC = 0x0 BPF_PROG_TYPE_SOCKET_FILTER = 0x1 BPF_PROG_TYPE_KPROBE = 0x2 @@ -2651,6 +2671,7 @@ const ( BPF_PROG_TYPE_EXT = 0x1c BPF_PROG_TYPE_LSM = 0x1d BPF_PROG_TYPE_SK_LOOKUP = 0x1e + BPF_PROG_TYPE_SYSCALL = 0x1f BPF_CGROUP_INET_INGRESS = 0x0 BPF_CGROUP_INET_EGRESS = 0x1 BPF_CGROUP_INET_SOCK_CREATE = 0x2 @@ -2689,6 +2710,12 @@ const ( BPF_XDP_CPUMAP = 0x23 BPF_SK_LOOKUP = 0x24 BPF_XDP = 0x25 + BPF_SK_SKB_VERDICT = 0x26 + BPF_SK_REUSEPORT_SELECT = 0x27 + BPF_SK_REUSEPORT_SELECT_OR_MIGRATE = 0x28 + BPF_PERF_EVENT = 0x29 + BPF_TRACE_KPROBE_MULTI = 0x2a + BPF_LSM_CGROUP = 0x2b BPF_LINK_TYPE_UNSPEC = 0x0 BPF_LINK_TYPE_RAW_TRACEPOINT = 0x1 BPF_LINK_TYPE_TRACING = 0x2 @@ -2696,6 +2723,9 @@ const ( BPF_LINK_TYPE_ITER = 0x4 BPF_LINK_TYPE_NETNS = 0x5 BPF_LINK_TYPE_XDP = 0x6 + BPF_LINK_TYPE_PERF_EVENT = 0x7 + BPF_LINK_TYPE_KPROBE_MULTI = 0x8 + BPF_LINK_TYPE_STRUCT_OPS = 0x9 BPF_ANY = 0x0 BPF_NOEXIST = 0x1 BPF_EXIST = 0x2 @@ -2733,6 +2763,7 @@ const ( BPF_F_ZERO_CSUM_TX = 0x2 BPF_F_DONT_FRAGMENT = 0x4 BPF_F_SEQ_NUMBER = 0x8 + BPF_F_TUNINFO_FLAGS = 0x10 BPF_F_INDEX_MASK = 0xffffffff BPF_F_CURRENT_CPU = 0xffffffff BPF_F_CTXLEN_MASK = 0xfffff00000000 @@ -2747,6 +2778,7 @@ const ( BPF_F_ADJ_ROOM_ENCAP_L4_GRE = 0x8 BPF_F_ADJ_ROOM_ENCAP_L4_UDP = 0x10 BPF_F_ADJ_ROOM_NO_CSUM_RESET = 0x20 + BPF_F_ADJ_ROOM_ENCAP_L2_ETH = 0x40 BPF_ADJ_ROOM_ENCAP_L2_MASK = 0xff BPF_ADJ_ROOM_ENCAP_L2_SHIFT = 0x38 BPF_F_SYSCTL_BASE_NAME = 0x1 @@ -2771,10 +2803,16 @@ const ( BPF_LWT_ENCAP_SEG6 = 0x0 BPF_LWT_ENCAP_SEG6_INLINE = 0x1 BPF_LWT_ENCAP_IP = 0x2 + BPF_F_BPRM_SECUREEXEC = 0x1 + BPF_F_BROADCAST = 0x8 + BPF_F_EXCLUDE_INGRESS = 0x10 + BPF_SKB_TSTAMP_UNSPEC = 0x0 + BPF_SKB_TSTAMP_DELIVERY_MONO = 0x1 BPF_OK = 0x0 BPF_DROP = 0x2 BPF_REDIRECT = 0x7 BPF_LWT_REROUTE = 0x80 + BPF_FLOW_DISSECTOR_CONTINUE = 0x81 BPF_SOCK_OPS_RTO_CB_FLAG = 0x1 BPF_SOCK_OPS_RETRANS_CB_FLAG = 0x2 BPF_SOCK_OPS_STATE_CB_FLAG = 0x4 @@ -2838,6 +2876,10 @@ const ( BPF_FIB_LKUP_RET_UNSUPP_LWT = 0x6 BPF_FIB_LKUP_RET_NO_NEIGH = 0x7 BPF_FIB_LKUP_RET_FRAG_NEEDED = 0x8 + BPF_MTU_CHK_SEGS = 0x1 + BPF_MTU_CHK_RET_SUCCESS = 0x0 + BPF_MTU_CHK_RET_FRAG_NEEDED = 0x1 + BPF_MTU_CHK_RET_SEGS_TOOBIG = 0x2 BPF_FD_TYPE_RAW_TRACEPOINT = 0x0 BPF_FD_TYPE_TRACEPOINT = 0x1 BPF_FD_TYPE_KPROBE = 0x2 @@ -2847,6 +2889,19 @@ const ( BPF_FLOW_DISSECTOR_F_PARSE_1ST_FRAG = 0x1 BPF_FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL = 0x2 BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP = 0x4 + BPF_CORE_FIELD_BYTE_OFFSET = 0x0 + BPF_CORE_FIELD_BYTE_SIZE = 0x1 + BPF_CORE_FIELD_EXISTS = 0x2 + BPF_CORE_FIELD_SIGNED = 0x3 + BPF_CORE_FIELD_LSHIFT_U64 = 0x4 + BPF_CORE_FIELD_RSHIFT_U64 = 0x5 + BPF_CORE_TYPE_ID_LOCAL = 0x6 + BPF_CORE_TYPE_ID_TARGET = 0x7 + BPF_CORE_TYPE_EXISTS = 0x8 + BPF_CORE_TYPE_SIZE = 0x9 + BPF_CORE_ENUMVAL_EXISTS = 0xa + BPF_CORE_ENUMVAL_VALUE = 0xb + BPF_CORE_TYPE_MATCHES = 0xc ) const ( @@ -3605,7 +3660,7 @@ const ( ETHTOOL_MSG_PSE_GET = 0x24 ETHTOOL_MSG_PSE_SET = 0x25 ETHTOOL_MSG_RSS_GET = 0x26 - ETHTOOL_MSG_USER_MAX = 0x26 + ETHTOOL_MSG_USER_MAX = 0x2b ETHTOOL_MSG_KERNEL_NONE = 0x0 ETHTOOL_MSG_STRSET_GET_REPLY = 0x1 ETHTOOL_MSG_LINKINFO_GET_REPLY = 0x2 @@ -3645,7 +3700,7 @@ const ( ETHTOOL_MSG_MODULE_NTF = 0x24 ETHTOOL_MSG_PSE_GET_REPLY = 0x25 ETHTOOL_MSG_RSS_GET_REPLY = 0x26 - ETHTOOL_MSG_KERNEL_MAX = 0x26 + ETHTOOL_MSG_KERNEL_MAX = 0x2b ETHTOOL_A_HEADER_UNSPEC = 0x0 ETHTOOL_A_HEADER_DEV_INDEX = 0x1 ETHTOOL_A_HEADER_DEV_NAME = 0x2 @@ -3749,7 +3804,7 @@ const ( ETHTOOL_A_RINGS_TCP_DATA_SPLIT = 0xb ETHTOOL_A_RINGS_CQE_SIZE = 0xc ETHTOOL_A_RINGS_TX_PUSH = 0xd - ETHTOOL_A_RINGS_MAX = 0xd + ETHTOOL_A_RINGS_MAX = 0x10 ETHTOOL_A_CHANNELS_UNSPEC = 0x0 ETHTOOL_A_CHANNELS_HEADER = 0x1 ETHTOOL_A_CHANNELS_RX_MAX = 0x2 @@ -3787,14 +3842,14 @@ const ( ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL = 0x17 ETHTOOL_A_COALESCE_USE_CQE_MODE_TX = 0x18 ETHTOOL_A_COALESCE_USE_CQE_MODE_RX = 0x19 - ETHTOOL_A_COALESCE_MAX = 0x19 + ETHTOOL_A_COALESCE_MAX = 0x1c ETHTOOL_A_PAUSE_UNSPEC = 0x0 ETHTOOL_A_PAUSE_HEADER = 0x1 ETHTOOL_A_PAUSE_AUTONEG = 0x2 ETHTOOL_A_PAUSE_RX = 0x3 ETHTOOL_A_PAUSE_TX = 0x4 ETHTOOL_A_PAUSE_STATS = 0x5 - ETHTOOL_A_PAUSE_MAX = 0x5 + ETHTOOL_A_PAUSE_MAX = 0x6 ETHTOOL_A_PAUSE_STAT_UNSPEC = 0x0 ETHTOOL_A_PAUSE_STAT_PAD = 0x1 ETHTOOL_A_PAUSE_STAT_TX_FRAMES = 0x2 @@ -4444,7 +4499,7 @@ const ( NL80211_ATTR_MAC_HINT = 0xc8 NL80211_ATTR_MAC_MASK = 0xd7 NL80211_ATTR_MAX_AP_ASSOC_STA = 0xca - NL80211_ATTR_MAX = 0x141 + NL80211_ATTR_MAX = 0x145 NL80211_ATTR_MAX_CRIT_PROT_DURATION = 0xb4 NL80211_ATTR_MAX_CSA_COUNTERS = 0xce NL80211_ATTR_MAX_MATCH_SETS = 0x85 @@ -4673,7 +4728,7 @@ const ( NL80211_BAND_ATTR_HT_CAPA = 0x4 NL80211_BAND_ATTR_HT_MCS_SET = 0x3 NL80211_BAND_ATTR_IFTYPE_DATA = 0x9 - NL80211_BAND_ATTR_MAX = 0xb + NL80211_BAND_ATTR_MAX = 0xd NL80211_BAND_ATTR_RATES = 0x2 NL80211_BAND_ATTR_VHT_CAPA = 0x8 NL80211_BAND_ATTR_VHT_MCS_SET = 0x7 @@ -4814,7 +4869,7 @@ const ( NL80211_CMD_LEAVE_IBSS = 0x2c NL80211_CMD_LEAVE_MESH = 0x45 NL80211_CMD_LEAVE_OCB = 0x6d - NL80211_CMD_MAX = 0x98 + NL80211_CMD_MAX = 0x99 NL80211_CMD_MICHAEL_MIC_FAILURE = 0x29 NL80211_CMD_MODIFY_LINK_STA = 0x97 NL80211_CMD_NAN_MATCH = 0x78 @@ -5795,6 +5850,8 @@ const ( TUN_F_TSO6 = 0x4 TUN_F_TSO_ECN = 0x8 TUN_F_UFO = 0x10 + TUN_F_USO4 = 0x20 + TUN_F_USO6 = 0x40 ) const ( @@ -5804,9 +5861,10 @@ const ( ) const ( - VIRTIO_NET_HDR_GSO_NONE = 0x0 - VIRTIO_NET_HDR_GSO_TCPV4 = 0x1 - VIRTIO_NET_HDR_GSO_UDP = 0x3 - VIRTIO_NET_HDR_GSO_TCPV6 = 0x4 - VIRTIO_NET_HDR_GSO_ECN = 0x80 + VIRTIO_NET_HDR_GSO_NONE = 0x0 + VIRTIO_NET_HDR_GSO_TCPV4 = 0x1 + VIRTIO_NET_HDR_GSO_UDP = 0x3 + VIRTIO_NET_HDR_GSO_TCPV6 = 0x4 + VIRTIO_NET_HDR_GSO_UDP_L4 = 0x5 + VIRTIO_NET_HDR_GSO_ECN = 0x80 ) diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_386.go b/vendor/golang.org/x/sys/unix/ztypes_linux_386.go index 4ecc1495cd..6d8acbcc57 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_386.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_386.go @@ -337,6 +337,8 @@ type Taskstats struct { Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Irq_count uint64 + Irq_delay_total uint64 } type cpuMask uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go index 34fddff964..59293c6884 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go @@ -350,6 +350,8 @@ type Taskstats struct { Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Irq_count uint64 + Irq_delay_total uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go b/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go index 3b14a6031f..40cfa38c29 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go @@ -328,6 +328,8 @@ type Taskstats struct { Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Irq_count uint64 + Irq_delay_total uint64 } type cpuMask uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go index 0517651ab3..055bc4216d 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go @@ -329,6 +329,8 @@ type Taskstats struct { Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Irq_count uint64 + Irq_delay_total uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go index 3b0c518134..f28affbc60 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go @@ -330,6 +330,8 @@ type Taskstats struct { Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Irq_count uint64 + Irq_delay_total uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go index fccdf4dd0f..9d71e7ccd8 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go @@ -333,6 +333,8 @@ type Taskstats struct { Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Irq_count uint64 + Irq_delay_total uint64 } type cpuMask uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go index 500de8fc07..fd5ccd332a 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go @@ -332,6 +332,8 @@ type Taskstats struct { Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Irq_count uint64 + Irq_delay_total uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go index d0434cd2c6..7704de77a2 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go @@ -332,6 +332,8 @@ type Taskstats struct { Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Irq_count uint64 + Irq_delay_total uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go index 84206ba534..df00b87571 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go @@ -333,6 +333,8 @@ type Taskstats struct { Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Irq_count uint64 + Irq_delay_total uint64 } type cpuMask uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go index ab078cf1f5..0942840db6 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go @@ -340,6 +340,8 @@ type Taskstats struct { Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Irq_count uint64 + Irq_delay_total uint64 } type cpuMask uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go index 42eb2c4cef..0348743950 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go @@ -339,6 +339,8 @@ type Taskstats struct { Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Irq_count uint64 + Irq_delay_total uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go index 31304a4e8b..bad0670475 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go @@ -339,6 +339,8 @@ type Taskstats struct { Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Irq_count uint64 + Irq_delay_total uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go index c311f9612d..83c69c119f 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go @@ -357,6 +357,8 @@ type Taskstats struct { Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Irq_count uint64 + Irq_delay_total uint64 } type cpuMask uint64 @@ -716,3 +718,26 @@ type SysvShmDesc struct { _ uint64 _ uint64 } + +type RISCVHWProbePairs struct { + Key int64 + Value uint64 +} + +const ( + RISCV_HWPROBE_KEY_MVENDORID = 0x0 + RISCV_HWPROBE_KEY_MARCHID = 0x1 + RISCV_HWPROBE_KEY_MIMPID = 0x2 + RISCV_HWPROBE_KEY_BASE_BEHAVIOR = 0x3 + RISCV_HWPROBE_BASE_BEHAVIOR_IMA = 0x1 + RISCV_HWPROBE_KEY_IMA_EXT_0 = 0x4 + RISCV_HWPROBE_IMA_FD = 0x1 + RISCV_HWPROBE_IMA_C = 0x2 + RISCV_HWPROBE_KEY_CPUPERF_0 = 0x5 + RISCV_HWPROBE_MISALIGNED_UNKNOWN = 0x0 + RISCV_HWPROBE_MISALIGNED_EMULATED = 0x1 + RISCV_HWPROBE_MISALIGNED_SLOW = 0x2 + RISCV_HWPROBE_MISALIGNED_FAST = 0x3 + RISCV_HWPROBE_MISALIGNED_UNSUPPORTED = 0x4 + RISCV_HWPROBE_MISALIGNED_MASK = 0x7 +) diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go b/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go index bba3cefac1..aa268d025c 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go @@ -352,6 +352,8 @@ type Taskstats struct { Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Irq_count uint64 + Irq_delay_total uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go index ad8a013804..444045b6c5 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go @@ -334,6 +334,8 @@ type Taskstats struct { Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Irq_count uint64 + Irq_delay_total uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/windows/env_windows.go b/vendor/golang.org/x/sys/windows/env_windows.go index 92ac05ff4e..b8ad192506 100644 --- a/vendor/golang.org/x/sys/windows/env_windows.go +++ b/vendor/golang.org/x/sys/windows/env_windows.go @@ -37,14 +37,14 @@ func (token Token) Environ(inheritExisting bool) (env []string, err error) { return nil, err } defer DestroyEnvironmentBlock(block) - blockp := uintptr(unsafe.Pointer(block)) + blockp := unsafe.Pointer(block) for { - entry := UTF16PtrToString((*uint16)(unsafe.Pointer(blockp))) + entry := UTF16PtrToString((*uint16)(blockp)) if len(entry) == 0 { break } env = append(env, entry) - blockp += 2 * (uintptr(len(entry)) + 1) + blockp = unsafe.Add(blockp, 2*(len(entry)+1)) } return env, nil } diff --git a/vendor/golang.org/x/sys/windows/exec_windows.go b/vendor/golang.org/x/sys/windows/exec_windows.go index 75980fd44a..a52e0331d8 100644 --- a/vendor/golang.org/x/sys/windows/exec_windows.go +++ b/vendor/golang.org/x/sys/windows/exec_windows.go @@ -95,12 +95,17 @@ func ComposeCommandLine(args []string) string { // DecomposeCommandLine breaks apart its argument command line into unescaped parts using CommandLineToArgv, // as gathered from GetCommandLine, QUERY_SERVICE_CONFIG's BinaryPathName argument, or elsewhere that // command lines are passed around. +// DecomposeCommandLine returns error if commandLine contains NUL. func DecomposeCommandLine(commandLine string) ([]string, error) { if len(commandLine) == 0 { return []string{}, nil } + utf16CommandLine, err := UTF16FromString(commandLine) + if err != nil { + return nil, errorspkg.New("string with NUL passed to DecomposeCommandLine") + } var argc int32 - argv, err := CommandLineToArgv(StringToUTF16Ptr(commandLine), &argc) + argv, err := CommandLineToArgv(&utf16CommandLine[0], &argc) if err != nil { return nil, err } diff --git a/vendor/golang.org/x/sys/windows/service.go b/vendor/golang.org/x/sys/windows/service.go index f8deca8397..c44a1b9636 100644 --- a/vendor/golang.org/x/sys/windows/service.go +++ b/vendor/golang.org/x/sys/windows/service.go @@ -141,6 +141,12 @@ const ( SERVICE_DYNAMIC_INFORMATION_LEVEL_START_REASON = 1 ) +type ENUM_SERVICE_STATUS struct { + ServiceName *uint16 + DisplayName *uint16 + ServiceStatus SERVICE_STATUS +} + type SERVICE_STATUS struct { ServiceType uint32 CurrentState uint32 @@ -212,6 +218,10 @@ type SERVICE_FAILURE_ACTIONS struct { Actions *SC_ACTION } +type SERVICE_FAILURE_ACTIONS_FLAG struct { + FailureActionsOnNonCrashFailures int32 +} + type SC_ACTION struct { Type uint32 Delay uint32 @@ -245,3 +255,4 @@ type QUERY_SERVICE_LOCK_STATUS struct { //sys UnsubscribeServiceChangeNotifications(subscription uintptr) = sechost.UnsubscribeServiceChangeNotifications? //sys RegisterServiceCtrlHandlerEx(serviceName *uint16, handlerProc uintptr, context uintptr) (handle Handle, err error) = advapi32.RegisterServiceCtrlHandlerExW //sys QueryServiceDynamicInformation(service Handle, infoLevel uint32, dynamicInfo unsafe.Pointer) (err error) = advapi32.QueryServiceDynamicInformation? +//sys EnumDependentServices(service Handle, activityState uint32, services *ENUM_SERVICE_STATUS, buffSize uint32, bytesNeeded *uint32, servicesReturned *uint32) (err error) = advapi32.EnumDependentServicesW diff --git a/vendor/golang.org/x/sys/windows/syscall_windows.go b/vendor/golang.org/x/sys/windows/syscall_windows.go index 3723b2c224..373d16388a 100644 --- a/vendor/golang.org/x/sys/windows/syscall_windows.go +++ b/vendor/golang.org/x/sys/windows/syscall_windows.go @@ -135,14 +135,14 @@ func Getpagesize() int { return 4096 } // NewCallback converts a Go function to a function pointer conforming to the stdcall calling convention. // This is useful when interoperating with Windows code requiring callbacks. -// The argument is expected to be a function with with one uintptr-sized result. The function must not have arguments with size larger than the size of uintptr. +// The argument is expected to be a function with one uintptr-sized result. The function must not have arguments with size larger than the size of uintptr. func NewCallback(fn interface{}) uintptr { return syscall.NewCallback(fn) } // NewCallbackCDecl converts a Go function to a function pointer conforming to the cdecl calling convention. // This is useful when interoperating with Windows code requiring callbacks. -// The argument is expected to be a function with with one uintptr-sized result. The function must not have arguments with size larger than the size of uintptr. +// The argument is expected to be a function with one uintptr-sized result. The function must not have arguments with size larger than the size of uintptr. func NewCallbackCDecl(fn interface{}) uintptr { return syscall.NewCallbackCDecl(fn) } @@ -405,7 +405,7 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys VerQueryValue(block unsafe.Pointer, subBlock string, pointerToBufferPointer unsafe.Pointer, bufSize *uint32) (err error) = version.VerQueryValueW // Process Status API (PSAPI) -//sys EnumProcesses(processIds []uint32, bytesReturned *uint32) (err error) = psapi.EnumProcesses +//sys enumProcesses(processIds *uint32, nSize uint32, bytesReturned *uint32) (err error) = psapi.EnumProcesses //sys EnumProcessModules(process Handle, module *Handle, cb uint32, cbNeeded *uint32) (err error) = psapi.EnumProcessModules //sys EnumProcessModulesEx(process Handle, module *Handle, cb uint32, cbNeeded *uint32, filterFlag uint32) (err error) = psapi.EnumProcessModulesEx //sys GetModuleInformation(process Handle, module Handle, modinfo *ModuleInfo, cb uint32) (err error) = psapi.GetModuleInformation @@ -1354,6 +1354,17 @@ func SetsockoptIPv6Mreq(fd Handle, level, opt int, mreq *IPv6Mreq) (err error) { return syscall.EWINDOWS } +func EnumProcesses(processIds []uint32, bytesReturned *uint32) error { + // EnumProcesses syscall expects the size parameter to be in bytes, but the code generated with mksyscall uses + // the length of the processIds slice instead. Hence, this wrapper function is added to fix the discrepancy. + var p *uint32 + if len(processIds) > 0 { + p = &processIds[0] + } + size := uint32(len(processIds) * 4) + return enumProcesses(p, size, bytesReturned) +} + func Getpid() (pid int) { return int(GetCurrentProcessId()) } func FindFirstFile(name *uint16, data *Win32finddata) (handle Handle, err error) { diff --git a/vendor/golang.org/x/sys/windows/types_windows.go b/vendor/golang.org/x/sys/windows/types_windows.go index 857acf1032..88e62a6385 100644 --- a/vendor/golang.org/x/sys/windows/types_windows.go +++ b/vendor/golang.org/x/sys/windows/types_windows.go @@ -2220,19 +2220,23 @@ type JOBOBJECT_BASIC_UI_RESTRICTIONS struct { } const ( - // JobObjectInformationClass + // JobObjectInformationClass for QueryInformationJobObject and SetInformationJobObject JobObjectAssociateCompletionPortInformation = 7 + JobObjectBasicAccountingInformation = 1 + JobObjectBasicAndIoAccountingInformation = 8 JobObjectBasicLimitInformation = 2 + JobObjectBasicProcessIdList = 3 JobObjectBasicUIRestrictions = 4 JobObjectCpuRateControlInformation = 15 JobObjectEndOfJobTimeInformation = 6 JobObjectExtendedLimitInformation = 9 JobObjectGroupInformation = 11 JobObjectGroupInformationEx = 14 - JobObjectLimitViolationInformation2 = 35 + JobObjectLimitViolationInformation = 13 + JobObjectLimitViolationInformation2 = 34 JobObjectNetRateControlInformation = 32 JobObjectNotificationLimitInformation = 12 - JobObjectNotificationLimitInformation2 = 34 + JobObjectNotificationLimitInformation2 = 33 JobObjectSecurityLimitInformation = 5 ) diff --git a/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/vendor/golang.org/x/sys/windows/zsyscall_windows.go index 6d2a268534..566dd3e315 100644 --- a/vendor/golang.org/x/sys/windows/zsyscall_windows.go +++ b/vendor/golang.org/x/sys/windows/zsyscall_windows.go @@ -86,6 +86,7 @@ var ( procDeleteService = modadvapi32.NewProc("DeleteService") procDeregisterEventSource = modadvapi32.NewProc("DeregisterEventSource") procDuplicateTokenEx = modadvapi32.NewProc("DuplicateTokenEx") + procEnumDependentServicesW = modadvapi32.NewProc("EnumDependentServicesW") procEnumServicesStatusExW = modadvapi32.NewProc("EnumServicesStatusExW") procEqualSid = modadvapi32.NewProc("EqualSid") procFreeSid = modadvapi32.NewProc("FreeSid") @@ -734,6 +735,14 @@ func DuplicateTokenEx(existingToken Token, desiredAccess uint32, tokenAttributes return } +func EnumDependentServices(service Handle, activityState uint32, services *ENUM_SERVICE_STATUS, buffSize uint32, bytesNeeded *uint32, servicesReturned *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procEnumDependentServicesW.Addr(), 6, uintptr(service), uintptr(activityState), uintptr(unsafe.Pointer(services)), uintptr(buffSize), uintptr(unsafe.Pointer(bytesNeeded)), uintptr(unsafe.Pointer(servicesReturned))) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func EnumServicesStatusEx(mgr Handle, infoLevel uint32, serviceType uint32, serviceState uint32, services *byte, bufSize uint32, bytesNeeded *uint32, servicesReturned *uint32, resumeHandle *uint32, groupName *uint16) (err error) { r1, _, e1 := syscall.Syscall12(procEnumServicesStatusExW.Addr(), 10, uintptr(mgr), uintptr(infoLevel), uintptr(serviceType), uintptr(serviceState), uintptr(unsafe.Pointer(services)), uintptr(bufSize), uintptr(unsafe.Pointer(bytesNeeded)), uintptr(unsafe.Pointer(servicesReturned)), uintptr(unsafe.Pointer(resumeHandle)), uintptr(unsafe.Pointer(groupName)), 0, 0) if r1 == 0 { @@ -3507,12 +3516,8 @@ func EnumProcessModulesEx(process Handle, module *Handle, cb uint32, cbNeeded *u return } -func EnumProcesses(processIds []uint32, bytesReturned *uint32) (err error) { - var _p0 *uint32 - if len(processIds) > 0 { - _p0 = &processIds[0] - } - r1, _, e1 := syscall.Syscall(procEnumProcesses.Addr(), 3, uintptr(unsafe.Pointer(_p0)), uintptr(len(processIds)), uintptr(unsafe.Pointer(bytesReturned))) +func enumProcesses(processIds *uint32, nSize uint32, bytesReturned *uint32) (err error) { + r1, _, e1 := syscall.Syscall(procEnumProcesses.Addr(), 3, uintptr(unsafe.Pointer(processIds)), uintptr(nSize), uintptr(unsafe.Pointer(bytesReturned))) if r1 == 0 { err = errnoErr(e1) } diff --git a/vendor/modules.txt b/vendor/modules.txt index 2c95f52560..ce5be23295 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -16,24 +16,12 @@ github.com/ActiveState/go-ogle-analytics # github.com/ActiveState/graphql v0.0.0-20230719154233-6949037a6e48 ## explicit github.com/ActiveState/graphql -# github.com/ActiveState/termtest v0.7.2 -## explicit; go 1.14 -github.com/ActiveState/termtest -github.com/ActiveState/termtest/internal/osutils -github.com/ActiveState/termtest/internal/osutils/stacktrace -# github.com/ActiveState/termtest/conpty v0.5.0 -## explicit; go 1.12 -github.com/ActiveState/termtest/conpty -# github.com/ActiveState/termtest/expect v0.7.0 -## explicit; go 1.12 -github.com/ActiveState/termtest/expect -github.com/ActiveState/termtest/expect/internal/osutils -# github.com/ActiveState/termtest/xpty v0.6.0 -## explicit; go 1.14 -github.com/ActiveState/termtest/xpty -# github.com/ActiveState/vt10x v1.3.1 +# github.com/ActiveState/pty v0.0.0-20230628221854-6fb90eb08a14 ## explicit; go 1.13 -github.com/ActiveState/vt10x +github.com/ActiveState/pty +# github.com/ActiveState/termtest v0.7.3-0.20230914171339-6e6462ec3e3f +## explicit; go 1.18 +github.com/ActiveState/termtest # github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 ## explicit github.com/Azure/go-ansiterm @@ -42,7 +30,6 @@ github.com/Azure/go-ansiterm/winterm ## explicit; go 1.16 # github.com/Netflix/go-expect v0.0.0-20201125194554-85d881c3777e ## explicit; go 1.13 -github.com/Netflix/go-expect # github.com/PuerkitoBio/purell v1.1.1 ## explicit github.com/PuerkitoBio/purell @@ -262,6 +249,9 @@ github.com/hashicorp/go-version ## explicit; go 1.12 github.com/hashicorp/golang-lru github.com/hashicorp/golang-lru/simplelru +# github.com/hinshun/vt10x v0.0.0-20220301184237-5011da428d02 +## explicit; go 1.14 +github.com/hinshun/vt10x # github.com/hpcloud/tail v1.0.0 ## explicit github.com/hpcloud/tail @@ -299,9 +289,6 @@ github.com/kballard/go-shellquote # github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd ## explicit github.com/kevinburke/ssh_config -# github.com/kr/pty v1.1.8 -## explicit; go 1.12 -github.com/kr/pty # github.com/labstack/echo/v4 v4.9.0 ## explicit; go 1.17 github.com/labstack/echo/v4 @@ -408,13 +395,17 @@ github.com/sergi/go-diff/diffmatchpatch # github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0 ## explicit github.com/shibukawa/configdir -# github.com/shirou/gopsutil/v3 v3.22.7 +# github.com/shirou/gopsutil/v3 v3.23.8 ## explicit; go 1.15 +github.com/shirou/gopsutil/v3/common github.com/shirou/gopsutil/v3/cpu github.com/shirou/gopsutil/v3/internal/common github.com/shirou/gopsutil/v3/mem github.com/shirou/gopsutil/v3/net github.com/shirou/gopsutil/v3/process +# github.com/shoenig/go-m1cpu v0.1.6 +## explicit; go 1.20 +github.com/shoenig/go-m1cpu # github.com/skratchdot/open-golang v0.0.0-20190104022628-a2dfa6d0dab6 ## explicit github.com/skratchdot/open-golang/open @@ -436,8 +427,8 @@ github.com/src-d/gcfg/types # github.com/stretchr/objx v0.5.0 ## explicit; go 1.12 github.com/stretchr/objx -# github.com/stretchr/testify v1.8.1 -## explicit; go 1.13 +# github.com/stretchr/testify v1.8.4 +## explicit; go 1.20 github.com/stretchr/testify/assert github.com/stretchr/testify/mock github.com/stretchr/testify/require @@ -445,11 +436,11 @@ github.com/stretchr/testify/suite # github.com/thoas/go-funk v0.8.0 ## explicit; go 1.13 github.com/thoas/go-funk -# github.com/tklauser/go-sysconf v0.3.10 +# github.com/tklauser/go-sysconf v0.3.12 ## explicit; go 1.13 github.com/tklauser/go-sysconf -# github.com/tklauser/numcpus v0.4.0 -## explicit; go 1.11 +# github.com/tklauser/numcpus v0.6.1 +## explicit; go 1.13 github.com/tklauser/numcpus # github.com/trivago/tgo v1.0.7 ## explicit @@ -488,7 +479,7 @@ github.com/xanzy/ssh-agent # github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 ## explicit github.com/xi2/xz -# github.com/yusufpapurcu/wmi v1.2.2 +# github.com/yusufpapurcu/wmi v1.2.3 ## explicit; go 1.16 github.com/yusufpapurcu/wmi # go.mongodb.org/mongo-driver v1.5.3 @@ -539,7 +530,7 @@ golang.org/x/net/http2/hpack golang.org/x/net/idna golang.org/x/net/internal/socks golang.org/x/net/proxy -# golang.org/x/sys v0.6.0 +# golang.org/x/sys v0.11.0 ## explicit; go 1.17 golang.org/x/sys/cpu golang.org/x/sys/execabs