Skip to content

Commit

Permalink
binaries: fix list error if binary is not a link
Browse files Browse the repository at this point in the history
If `tarantool` binary is not a symlink, try to execute it
to get version. Use this version in versions list.
  • Loading branch information
psergee committed Feb 19, 2024
1 parent c98976b commit 9f8eb5c
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 23 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ empty, for example.
- `tt pack` with `--use-docker` fails due to incompatible versions of `tt`
between local system and docker container. Install current `tt` version
in docker image if possible.
- `tt binaries list` invalid argument error if `tarantool` is not a symlink.

## [2.1.2] - 2024-02-02

Expand Down
54 changes: 33 additions & 21 deletions cli/binary/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,33 +34,45 @@ func printVersion(versionString string) {
func ParseBinaries(fileList []fs.DirEntry, programName string,
binDir string) ([]version.Version, error) {
var binaryVersions []version.Version
symlinkName := programName

if programName == search.ProgramDev {
binActive, isTarantoolBinary, err := install.IsTarantoolDev(
filepath.Join(binDir, "tarantool"),
binDir,
)
if err != nil {
return binaryVersions, err
}
if isTarantoolBinary {
binaryVersions = append(binaryVersions,
version.Version{Str: programName + " -> " + binActive + " [active]"})
}
return binaryVersions, nil
}

if programName == search.ProgramEe {
symlinkName := programName
if programName == search.ProgramEe || programName == search.ProgramDev {
symlinkName = search.ProgramCe
}
binActive, err := util.ResolveSymlink(filepath.Join(binDir, symlinkName))
if err != nil && !os.IsNotExist(err) {
return binaryVersions, err

binActive := ""
programPath := filepath.Join(binDir, symlinkName)
if fileInfo, err := os.Lstat(programPath); err == nil {
if programName == search.ProgramDev &&
fileInfo.Mode()&os.ModeSymlink == os.ModeSymlink {
binActive, isTarantoolBinary, err := install.IsTarantoolDev(programPath, binDir)
if err != nil {
return binaryVersions, err
}
if isTarantoolBinary {
binaryVersions = append(binaryVersions,
version.Version{Str: programName + " -> " + binActive + " [active]"})
}
return binaryVersions, nil
} else if programName == search.ProgramCe && fileInfo.Mode()&os.ModeSymlink == 0 {
tntCli := cmdcontext.TarantoolCli{Executable: programPath}
binaryVersion, err := tntCli.GetVersion()
if err != nil {
return binaryVersions, err
}
binaryVersion.Str += " [active]"
binaryVersions = append(binaryVersions, binaryVersion)
} else {
binActive, err = util.ResolveSymlink(programPath)
if err != nil && !os.IsNotExist(err) {
return binaryVersions, err
}
binActive = filepath.Base(binActive)
}
}
binActive = filepath.Base(binActive)

versionPrefix := programName + version.FsSeparator
var err error
for _, f := range fileList {
if strings.HasPrefix(f.Name(), versionPrefix) {
versionStr := strings.TrimPrefix(strings.TrimPrefix(f.Name(), versionPrefix), "v")
Expand Down
43 changes: 42 additions & 1 deletion cli/binary/list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ package binary
import (
"fmt"
"os"
"path/filepath"
"sort"
"strings"
"testing"

"github.com/otiai10/copy"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tarantool/tt/cli/version"
Expand All @@ -33,10 +35,49 @@ func TestParseBinariesTarantoolDev(t *testing.T) {
assert.NoError(t, err)
versions, err := ParseBinaries(fileList, "tarantool-dev", testDir)
assert.NoError(t, err)
assert.Equal(t, 1, len(versions))
require.Equal(t, 1, len(versions))
version := versions[0].Str
assert.True(t, strings.HasPrefix(version, "tarantool-dev"))
assert.True(t, strings.HasSuffix(version, "[active]"))
})
}
}

func TestParseBinariesNoSymlink(t *testing.T) {
tmpDir := t.TempDir()
require.NoError(t, copy.Copy("./testdata/no_symlink", tmpDir))

fileList, err := os.ReadDir(tmpDir)
require.NoError(t, err)
versions, err := ParseBinaries(fileList, "tarantool", tmpDir)
require.NoError(t, err)
sort.Stable(sort.Reverse(version.VersionSlice(versions)))
expectedSortedVersions := []string{"3.1.0-entrypoint-83-gcb0264c3c [active]", "2.10.1"}
require.Equal(t, len(expectedSortedVersions), len(versions))
for i := 0; i < len(expectedSortedVersions); i++ {
assert.Equal(t, expectedSortedVersions[i], versions[i].Str)
}
versions, err = ParseBinaries(fileList, "tarantool-ee", tmpDir)
require.NoError(t, err)
sort.Stable(sort.Reverse(version.VersionSlice(versions)))
expectedSortedVersions = []string{"2.11.1"}
require.Equal(t, len(expectedSortedVersions), len(versions))
for i := 0; i < len(expectedSortedVersions); i++ {
assert.Equal(t, expectedSortedVersions[i], versions[i].Str)
}

// Tarantool exists, but not executable.
require.NoError(t, os.Chmod(filepath.Join(tmpDir, "tarantool"), 0440))
versions, err = ParseBinaries(fileList, "tarantool-ee", tmpDir)
require.NoError(t, err)
sort.Stable(sort.Reverse(version.VersionSlice(versions)))
expectedSortedVersions = []string{"2.11.1"}
require.Equal(t, len(expectedSortedVersions), len(versions))
for i := 0; i < len(expectedSortedVersions); i++ {
assert.Equal(t, expectedSortedVersions[i], versions[i].Str)
}

require.NoError(t, os.Chmod(filepath.Join(tmpDir, "tarantool"), 0440))
_, err = ParseBinaries(fileList, "tarantool", tmpDir)
require.ErrorContains(t, err, "failed to get tarantool version")
}
3 changes: 3 additions & 0 deletions cli/binary/testdata/no_symlink/tarantool
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/sh

echo 'Tarantool 3.1.0-entrypoint-83-gcb0264c3c'
Empty file.
Empty file.
44 changes: 43 additions & 1 deletion test/integration/binaries/test_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import shutil
import subprocess

from utils import config_name
from utils import config_name, run_command_and_get_output


def test_list(tt_cmd, tmpdir):
Expand Down Expand Up @@ -106,3 +106,45 @@ def test_list_tarantool_dev(tt_cmd, tmpdir):
assert "2.10.7" in output
assert "1.10.0" in output
assert "tarantool-dev" in output


def test_list_tarantool_no_symlink(tt_cmd, tmpdir):
# Copy the test bin_dir to the "run" directory.
test_app_path = os.path.join(os.path.dirname(__file__), "bin")
shutil.copytree(test_app_path, tmpdir + "/bin", True)

configPath = os.path.join(tmpdir, config_name)
# Create test config
with open(configPath, 'w') as f:
f.write('tt:\n env:\n bin_dir: "./bin"\n inc_dir:\n')

os.remove(os.path.join(tmpdir, "bin", "tarantool"))
with open(os.path.join(tmpdir, "bin", "tarantool"), "w") as tnt_file:
tnt_file.write("""#!/bin/sh
echo 'Tarantool 3.1.0-entrypoint-83-gcb0264c3c'""")
os.chmod(os.path.join(tmpdir, "bin", "tarantool"), 0o750)

# Print binaries
binaries_cmd = [tt_cmd, "--cfg", configPath, "binaries", "list"]
rc, output = run_command_and_get_output(binaries_cmd, cwd=tmpdir)

assert rc == 0
assert "tt" in output
assert "0.1.0" in output
assert "tarantool:" in output
assert "2.10.3" in output
assert "2.8.1" in output
assert "3.1.0-entrypoint-83-gcb0264c3c [active]" in output

# Remove non-versioned tarantool binary.
os.remove(os.path.join(tmpdir, "bin", "tarantool"))
binaries_cmd = [tt_cmd, "--cfg", configPath, "binaries", "list"]
rc, output = run_command_and_get_output(binaries_cmd, cwd=tmpdir)

assert rc == 0
assert "tt" in output
assert "0.1.0" in output
assert "tarantool:" in output
assert "2.10.3" in output
assert "2.8.1" in output
assert "[active]" not in output # No active tarantool.

0 comments on commit 9f8eb5c

Please sign in to comment.