diff --git a/internal/integrationtest/main/main_test.go b/internal/integrationtest/main/main_test.go new file mode 100644 index 00000000000..940118410ff --- /dev/null +++ b/internal/integrationtest/main/main_test.go @@ -0,0 +1,166 @@ +// This file is part of arduino-cli. +// +// Copyright 2022 ARDUINO SA (http://www.arduino.cc/) +// +// This software is released under the GNU General Public License version 3, +// which covers the main part of arduino-cli. +// The terms of this license can be found at: +// https://www.gnu.org/licenses/gpl-3.0.en.html +// +// You can be released from the requirements of the above licenses by purchasing +// a commercial license. Buying such a license is mandatory if you want to +// modify or otherwise use the software for commercial activities involving the +// Arduino software without disclosing the source code of your own applications. +// To purchase a commercial license, send an email to license@arduino.cc. + +package main_test + +import ( + "encoding/json" + "strings" + "testing" + + "github.com/arduino/arduino-cli/internal/integrationtest" + "github.com/arduino/go-paths-helper" + "github.com/stretchr/testify/require" + semver "go.bug.st/relaxed-semver" + "go.bug.st/testsuite" + "go.bug.st/testsuite/requirejson" +) + +func TestHelp(t *testing.T) { + env := testsuite.NewEnvironment(t) + defer env.CleanUp() + + cli := integrationtest.NewArduinoCliWithinEnvironment(env, &integrationtest.ArduinoCLIConfig{ + ArduinoCLIPath: paths.New("..", "..", "..", "arduino-cli"), + UseSharedStagingFolder: true, + }) + + // Run help and check the output message + stdout, stderr, err := cli.Run("help") + require.NoError(t, err) + require.Empty(t, stderr) + require.Contains(t, string(stdout), "Usage") +} + +func TestVersion(t *testing.T) { + env := testsuite.NewEnvironment(t) + defer env.CleanUp() + + cli := integrationtest.NewArduinoCliWithinEnvironment(env, &integrationtest.ArduinoCLIConfig{ + ArduinoCLIPath: paths.New("..", "..", "..", "arduino-cli"), + UseSharedStagingFolder: true, + }) + + // Run version and check the output message + stdout, stderr, err := cli.Run("version") + require.NoError(t, err) + require.Contains(t, string(stdout), "Version:") + require.Contains(t, string(stdout), "Commit:") + require.Empty(t, stderr) + + // Checks if "version --format json" has a json as an output + stdout, _, err = cli.Run("version", "--format", "json") + require.NoError(t, err) + var jsonMap map[string]string + err = json.Unmarshal(stdout, &jsonMap) + require.NoError(t, err) + + // Checks if Application's value is arduino-cli + require.Equal(t, jsonMap["Application"], "arduino-cli") + + // Checks if VersionString's value is git-snapshot, nightly or a valid semantic versioning + switch version := jsonMap["VersionString"]; version { + case "git-snapshot": + require.Contains(t, version, "git-snapshot") + case "nigthly": + require.Contains(t, version, "nightly") + default: + _, err = semver.Parse(version) + require.NoError(t, err) + } + + // Checks if Commit's value is not empty + require.NotEmpty(t, jsonMap["Commit"]) +} + +func TestLogOptions(t *testing.T) { + // Using version as a test command + env := testsuite.NewEnvironment(t) + defer env.CleanUp() + + cli := integrationtest.NewArduinoCliWithinEnvironment(env, &integrationtest.ArduinoCLIConfig{ + ArduinoCLIPath: paths.New("..", "..", "..", "arduino-cli"), + UseSharedStagingFolder: true, + }) + + // No logs + stdout, _, err := cli.Run("version") + require.NoError(t, err) + trimOut := strings.TrimSpace(string(stdout)) + outLines := strings.Split(trimOut, "\n") + require.Len(t, outLines, 1) + + // Plain text logs on stdout + stdout, _, err = cli.Run("version", "-v") + require.NoError(t, err) + trimOut = strings.TrimSpace(string(stdout)) + outLines = strings.Split(trimOut, "\n") + require.Greater(t, len(outLines), 1) + require.True(t, strings.HasPrefix(outLines[0], "\x1b[36mINFO\x1b[0m")) // account for the colors + + // Plain text logs on file + logFile := cli.DataDir().Join("log.txt") + _, _, err = cli.Run("version", "--log-file", logFile.String()) + require.NoError(t, err) + lines, _ := logFile.ReadFileAsLines() + require.True(t, strings.HasPrefix(lines[0], "time=\"")) + + // json on stdout + stdout, _, err = cli.Run("version", "-v", "--log-format", "JSON") + require.NoError(t, err) + trimOut = strings.TrimSpace(string(stdout)) + outLines = strings.Split(trimOut, "\n") + requirejson.Contains(t, []byte(outLines[0]), `{ "level" }`) + + // Check if log.json contains readable json in each line + var v interface{} + logFileJson := cli.DataDir().Join("log.json") + _, _, err = cli.Run("version", "--log-format", "JSON", "--log-file", logFileJson.String()) + require.NoError(t, err) + fileContent, err := logFileJson.ReadFileAsLines() + require.NoError(t, err) + for _, line := range fileContent { + // exclude empty lines since they are not valid json + if line == "" { + continue + } + err = json.Unmarshal([]byte(line), &v) + require.NoError(t, err) + } +} + +func TestInventoryCreation(t *testing.T) { + // Using version as a test command + env := testsuite.NewEnvironment(t) + defer env.CleanUp() + + cli := integrationtest.NewArduinoCliWithinEnvironment(env, &integrationtest.ArduinoCLIConfig{ + ArduinoCLIPath: paths.New("..", "..", "..", "arduino-cli"), + UseSharedStagingFolder: true, + }) + + // no logs + stdout, _, err := cli.Run("version") + require.NoError(t, err) + line := strings.TrimSpace(string(stdout)) + outLines := strings.Split(line, "\n") + require.Len(t, outLines, 1) + + // parse inventory file + inventoryFile := cli.DataDir().Join("inventory.yaml") + stream, err := inventoryFile.ReadFile() + require.NoError(t, err) + require.True(t, strings.Contains(string(stream), "installation")) +} diff --git a/test/test_main.py b/test/test_main.py deleted file mode 100644 index 91cddc57732..00000000000 --- a/test/test_main.py +++ /dev/null @@ -1,92 +0,0 @@ -# This file is part of arduino-cli. -# -# Copyright 2020 ARDUINO SA (http://www.arduino.cc/) -# -# This software is released under the GNU General Public License version 3, -# which covers the main part of arduino-cli. -# The terms of this license can be found at: -# https://www.gnu.org/licenses/gpl-3.0.en.html -# -# You can be released from the requirements of the above licenses by purchasing -# a commercial license. Buying such a license is mandatory if you want to modify or -# otherwise use the software for commercial activities involving the Arduino -# software without disclosing the source code of your own applications. To purchase -# a commercial license, send an email to license@arduino.cc. -import json -import os - -import semver -import yaml - - -def test_help(run_command): - result = run_command(["help"]) - assert result.ok - assert result.stderr == "" - assert "Usage" in result.stdout - - -def test_version(run_command): - result = run_command(["version"]) - assert result.ok - assert "Version:" in result.stdout - assert "Commit:" in result.stdout - assert "" == result.stderr - - result = run_command(["version", "--format", "json"]) - assert result.ok - parsed_out = json.loads(result.stdout) - assert parsed_out.get("Application", False) == "arduino-cli" - version = parsed_out.get("VersionString", False) - assert semver.VersionInfo.isvalid(version=version) or "git-snapshot" in version or "nightly" in version - assert isinstance(parsed_out.get("Commit", False), str) - - -def test_log_options(run_command, data_dir): - """ - using `version` as a test command - """ - - # no logs - out_lines = run_command(["version"]).stdout.strip().split("\n") - assert len(out_lines) == 1 - - # plain text logs on stdoud - out_lines = run_command(["version", "-v"]).stdout.strip().split("\n") - assert len(out_lines) > 1 - assert out_lines[0].startswith("\x1b[36mINFO\x1b[0m") # account for the colors - - # plain text logs on file - log_file = os.path.join(data_dir, "log.txt") - run_command(["version", "--log-file", log_file]) - with open(log_file) as f: - lines = f.readlines() - assert lines[0].startswith('time="') # file format is different from console - - # json on stdout - out_lines = run_command(["version", "-v", "--log-format", "JSON"]).stdout.strip().split("\n") - lg = json.loads(out_lines[0]) - assert "level" in lg - - # json on file - log_file = os.path.join(data_dir, "log.json") - run_command(["version", "--log-format", "json", "--log-file", log_file]) - with open(log_file) as f: - for line in f.readlines(): - json.loads(line) - - -def test_inventory_creation(run_command, data_dir): - """ - using `version` as a test command - """ - - # no logs - out_lines = run_command(["version"]).stdout.strip().split("\n") - assert len(out_lines) == 1 - - # parse inventory file - inventory_file = os.path.join(data_dir, "inventory.yaml") - with open(inventory_file, "r") as stream: - inventory = yaml.safe_load(stream) - assert "installation" in inventory