github.com/mysteriumnetwork/node@v0.0.0-20240516044423-365054f76801/ci/test/testinstall/install_integration_test.go (about)

     1  //go:build integration
     2  
     3  /*
     4   * Copyright (C) 2020 The "MysteriumNetwork/node" Authors.
     5   *
     6   * This program is free software: you can redistribute it and/or modify
     7   * it under the terms of the GNU General Public License as published by
     8   * the Free Software Foundation, either version 3 of the License, or
     9   * (at your option) any later version.
    10   *
    11   * This program is distributed in the hope that it will be useful,
    12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14   * GNU General Public License for more details.
    15   *
    16   * You should have received a copy of the GNU General Public License
    17   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    18   */
    19  
    20  package testinstall
    21  
    22  import (
    23  	"bufio"
    24  	"encoding/json"
    25  	"fmt"
    26  	"strings"
    27  	"testing"
    28  	"time"
    29  
    30  	"github.com/magefile/mage/sh"
    31  	"github.com/rs/zerolog/log"
    32  	"github.com/stretchr/testify/assert"
    33  )
    34  
    35  const (
    36  	installFile = "install.sh"
    37  )
    38  
    39  // TestInstall tests installation on various Linux distributions.
    40  // SystemD docker images based on https://github.com/j8r/dockerfiles
    41  // Installs myst using install.sh, tests for healthcheck output.
    42  func TestInstall(t *testing.T) {
    43  	t.Parallel()
    44  
    45  	images := []string{
    46  		"debian-buster",
    47  		"debian-stretch",
    48  		"ubuntu-bionic",
    49  		"ubuntu-focal",
    50  		"ubuntu-impish",
    51  		"ubuntu-jammy",
    52  	}
    53  	for _, img := range images {
    54  		t.Run(img, func(t *testing.T) {
    55  			testImage(t, img)
    56  		})
    57  	}
    58  }
    59  
    60  func testImage(t *testing.T, image string) {
    61  	assert := assert.New(t)
    62  	failIf := failIfFunc(t)
    63  
    64  	buildOutput, err := sh.Output("docker", "build",
    65  		"-f", "Dockerfile."+image,
    66  		"-t", "testinstall_"+image,
    67  		".",
    68  	)
    69  	failIf(err)
    70  
    71  	var imageId string
    72  	scanner := bufio.NewScanner(strings.NewReader(buildOutput))
    73  	for scanner.Scan() {
    74  		line := scanner.Text()
    75  		fmt.Println(line)
    76  		if strings.HasPrefix(line, "Successfully built") {
    77  			fields := strings.Fields(line)
    78  			imageId = fields[len(fields)-1]
    79  		}
    80  	}
    81  	failIf(scanner.Err())
    82  	assert.NotEmpty(imageId)
    83  
    84  	runOutput, err := sh.Output("docker", "run",
    85  		"-d", "--privileged",
    86  		"-v", "/sys/fs/cgroup:/sys/fs/cgroup:ro",
    87  		imageId,
    88  	)
    89  	failIf(err)
    90  
    91  	var containerId string
    92  	scanner = bufio.NewScanner(strings.NewReader(runOutput))
    93  	for scanner.Scan() {
    94  		line := scanner.Text()
    95  		fmt.Println(line)
    96  		containerId = strings.TrimSpace(line)[0:12]
    97  	}
    98  
    99  	defer sh.RunV("docker", "kill", containerId)
   100  
   101  	failIf(scanner.Err())
   102  	assert.NotEmpty(containerId)
   103  
   104  	err = sh.RunV("docker", "cp", "../../../"+installFile, containerId+":/")
   105  	failIf(err)
   106  	err = sh.RunV("docker", "exec", containerId, "bash", installFile)
   107  	failIf(err)
   108  
   109  	tb := time.Now()
   110  	assert.Eventually(func() bool {
   111  		return tequilaIsHealthy(t, containerId)
   112  	}, 30*time.Second, 500*time.Millisecond)
   113  	log.Info().Msgf("Startup took, ms: %d", time.Since(tb).Milliseconds())
   114  }
   115  
   116  func tequilaIsHealthy(t *testing.T, containerId string) bool {
   117  	var healthcheckOutput struct {
   118  		Uptime string `json:"uptime"`
   119  	}
   120  	healthcheckJSON, err := sh.Output("docker", "exec", containerId, "curl", "-s", "localhost:4050/healthcheck")
   121  	if err != nil {
   122  		return false
   123  	}
   124  	fmt.Println(healthcheckJSON)
   125  	err = json.Unmarshal([]byte(healthcheckJSON), &healthcheckOutput)
   126  	failIfFunc(t)(err)
   127  	assert.NotEmpty(t, healthcheckOutput.Uptime)
   128  	return true
   129  }
   130  
   131  func failIfFunc(t *testing.T) func(error) {
   132  	return func(err error) {
   133  		if err != nil {
   134  			assert.FailNow(t, "Fatal error occurred: "+err.Error())
   135  		}
   136  	}
   137  }