go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/cli/progress/multiprogress_test.go (about)

     1  // Copyright (c) Mondoo, Inc.
     2  // SPDX-License-Identifier: BUSL-1.1
     3  
     4  package progress
     5  
     6  import (
     7  	"bytes"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/stretchr/testify/assert"
    12  	"github.com/stretchr/testify/require"
    13  )
    14  
    15  func TestMultiProgressBar(t *testing.T) {
    16  	var in bytes.Buffer
    17  	var buf bytes.Buffer
    18  
    19  	progressBarElements := map[string]string{"1": "test1", "2": "test2", "3": "test3"}
    20  	multiprogress, err := newMultiProgressBarsMock(progressBarElements, []string{"1", "2", "3"}, &in, &buf)
    21  	require.NoError(t, err)
    22  
    23  	go func() {
    24  		// we need to wait for tea to start the Program, otherwise these would be no-ops
    25  		time.Sleep(1 * time.Millisecond)
    26  		multiprogress.OnProgress("1", 0.5)
    27  		multiprogress.OnProgress("2", 0.5)
    28  		multiprogress.OnProgress("1", 1.0)
    29  		multiprogress.Score("1", "F")
    30  		multiprogress.Completed("1")
    31  		multiprogress.Close()
    32  	}()
    33  	err = multiprogress.Open()
    34  	require.NoError(t, err)
    35  
    36  	assert.Contains(t, buf.String(), "test1                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% score: F")
    37  	assert.Contains(t, buf.String(), "test2                           ━━━━━━━━━━━━━━━━━━─────────────────  50%")
    38  	assert.Contains(t, buf.String(), "1/3 scanned                     ━━━━━━━━━━━━━━━━━━─────────────────  50%")
    39  	assert.Contains(t, buf.String(), "... 1 more asset ...")
    40  }
    41  
    42  func TestMultiProgressBarSingleAsset(t *testing.T) {
    43  	var in bytes.Buffer
    44  	var buf bytes.Buffer
    45  
    46  	progressBarElements := map[string]string{"1": "test1"}
    47  	multiprogress, err := newMultiProgressBarsMock(progressBarElements, []string{"1"}, &in, &buf)
    48  	require.NoError(t, err)
    49  
    50  	go func() {
    51  		// we need to wait for tea to start the Program, otherwise these would be no-ops
    52  		time.Sleep(1 * time.Millisecond)
    53  		multiprogress.OnProgress("1", 0.5)
    54  		multiprogress.OnProgress("2", 0.5)
    55  		multiprogress.OnProgress("1", 1.0)
    56  		multiprogress.Score("1", "F")
    57  		multiprogress.Completed("1")
    58  		multiprogress.Close()
    59  	}()
    60  	err = multiprogress.Open()
    61  	require.NoError(t, err)
    62  	assert.Contains(t, buf.String(), "test1 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% score: F")
    63  	assert.NotContains(t, buf.String(), "test2")
    64  	assert.NotContains(t, buf.String(), "scanned")
    65  }
    66  
    67  func TestMultiProgressBarFinished(t *testing.T) {
    68  	var in bytes.Buffer
    69  	var buf bytes.Buffer
    70  
    71  	progressBarElements := map[string]string{"1": "test1", "2": "test2", "3": "test3"}
    72  	multiprogress, err := newMultiProgressBarsMock(progressBarElements, []string{"1", "2", "3"}, &in, &buf)
    73  	require.NoError(t, err)
    74  
    75  	go func() {
    76  		// we need to wait for tea to start the Program, otherwise these would be no-ops
    77  		time.Sleep(1 * time.Millisecond)
    78  		multiprogress.OnProgress("1", 1.0)
    79  		multiprogress.OnProgress("2", 1.0)
    80  		multiprogress.OnProgress("3", 1.0)
    81  		multiprogress.Score("1", "F")
    82  		multiprogress.Completed("1")
    83  		multiprogress.Score("2", "F")
    84  		multiprogress.Completed("2")
    85  		multiprogress.Score("3", "F")
    86  		multiprogress.Completed("3")
    87  	}()
    88  	err = multiprogress.Open()
    89  	require.NoError(t, err)
    90  
    91  	assert.Contains(t, buf.String(), "test1                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% score: F")
    92  	assert.Contains(t, buf.String(), "test2                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% score: F")
    93  	assert.Contains(t, buf.String(), "test3                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% score: F")
    94  	assert.Contains(t, buf.String(), "3/3 scanned                     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100%")
    95  	assert.NotContains(t, buf.String(), "errored")
    96  }
    97  
    98  func TestMultiProgressBarErrored(t *testing.T) {
    99  	var in bytes.Buffer
   100  	var buf bytes.Buffer
   101  
   102  	progressBarElements := map[string]string{"1": "test1", "2": "test2", "3": "test3"}
   103  	multiprogress, err := newMultiProgressBarsMock(progressBarElements, []string{"1", "2", "3"}, &in, &buf)
   104  	require.NoError(t, err)
   105  
   106  	go func() {
   107  		// we need to wait for tea to start the Program, otherwise these would be no-ops
   108  		time.Sleep(1 * time.Millisecond)
   109  		multiprogress.OnProgress("1", 1.0)
   110  		multiprogress.Score("1", "F")
   111  		multiprogress.Completed("1")
   112  		multiprogress.Score("2", "X")
   113  		multiprogress.Errored("2")
   114  		multiprogress.OnProgress("3", 1.0)
   115  		multiprogress.Score("3", "F")
   116  		multiprogress.Completed("3")
   117  	}()
   118  	err = multiprogress.Open()
   119  	require.NoError(t, err)
   120  	assert.Contains(t, buf.String(), "test1                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% score: F")
   121  	assert.Contains(t, buf.String(), "test2                           ───────────────────────────────────    X")
   122  	assert.Contains(t, buf.String(), "test3                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% score: F")
   123  	assert.Contains(t, buf.String(), "2/3 scanned 1/3 errored         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100%")
   124  }
   125  
   126  func TestMultiProgressBarLastErrored(t *testing.T) {
   127  	var in bytes.Buffer
   128  	var buf bytes.Buffer
   129  
   130  	progressBarElements := map[string]string{"1": "test1", "2": "test2", "3": "test3"}
   131  	multiprogress, err := newMultiProgressBarsMock(progressBarElements, []string{"1", "2", "3"}, &in, &buf)
   132  	require.NoError(t, err)
   133  
   134  	go func() {
   135  		// we need to wait for tea to start the Program, otherwise these would be no-ops
   136  		time.Sleep(1 * time.Millisecond)
   137  		multiprogress.OnProgress("1", 1.0)
   138  		multiprogress.OnProgress("2", 1.0)
   139  		multiprogress.Score("1", "F")
   140  		multiprogress.Completed("1")
   141  		multiprogress.Score("2", "F")
   142  		multiprogress.Completed("2")
   143  		multiprogress.Score("3", "X")
   144  		multiprogress.Errored("3")
   145  	}()
   146  	err = multiprogress.Open()
   147  	require.NoError(t, err)
   148  	assert.Contains(t, buf.String(), "test1                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% score: F")
   149  	assert.Contains(t, buf.String(), "test2                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% score: F")
   150  	assert.Contains(t, buf.String(), "test3                           ───────────────────────────────────    X")
   151  	assert.Contains(t, buf.String(), "2/3 scanned 1/3 errored         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100%")
   152  }
   153  
   154  func TestMultiProgressBarOnlyOneErrored(t *testing.T) {
   155  	var in bytes.Buffer
   156  	var buf bytes.Buffer
   157  
   158  	progressBarElements := map[string]string{"1": "test1"}
   159  	multiprogress, err := newMultiProgressBarsMock(progressBarElements, []string{"1"}, &in, &buf)
   160  	require.NoError(t, err)
   161  
   162  	go func() {
   163  		// we need to wait for tea to start the Program, otherwise these would be no-ops
   164  		time.Sleep(1 * time.Millisecond)
   165  		// this should also end the tea program
   166  		multiprogress.Errored("1")
   167  		multiprogress.Close()
   168  	}()
   169  	err = multiprogress.Open()
   170  	require.NoError(t, err)
   171  
   172  	assert.Contains(t, buf.String(), "test1 ───────────────────────────────────    X")
   173  	assert.NotContains(t, buf.String(), "0/1 scanned 1/1 errored")
   174  }
   175  
   176  func TestMultiProgressBarLimitedOneMore(t *testing.T) {
   177  	var in bytes.Buffer
   178  	var buf bytes.Buffer
   179  
   180  	progressBarElements := map[string]string{"1": "test1", "2": "test2", "3": "test3", "4": "test4"}
   181  	multiprogress, err := newMultiProgressBarsMock(progressBarElements, []string{"1", "2", "3", "4"}, &in, &buf)
   182  	require.NoError(t, err)
   183  
   184  	go func() {
   185  		// we need to wait for tea to start the Program, otherwise these would be no-ops
   186  		time.Sleep(1 * time.Millisecond)
   187  		multiprogress.OnProgress("1", 1.0)
   188  		multiprogress.OnProgress("2", 0.1)
   189  		multiprogress.Score("1", "F")
   190  		multiprogress.Completed("1")
   191  		multiprogress.Close()
   192  	}()
   193  	err = multiprogress.Open()
   194  	require.NoError(t, err)
   195  	assert.Contains(t, buf.String(), "test1                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% score: F")
   196  	assert.Contains(t, buf.String(), "test2                           ━━━━───────────────────────────────  10%")
   197  	assert.Contains(t, buf.String(), "1/4 scanned                     ━━━━━━━━━──────────────────────────  27%")
   198  	assert.Contains(t, buf.String(), "2 more assets")
   199  }
   200  
   201  func TestMultiProgressBarError(t *testing.T) {
   202  	var in bytes.Buffer
   203  	var buf bytes.Buffer
   204  
   205  	progressBarElements := map[string]string{"1": "test1", "2": "test2", "3": "test3"}
   206  	_, err := newMultiProgressBarsMock(progressBarElements, []string{"1", "3"}, &in, &buf)
   207  	require.Error(t, err)
   208  }
   209  
   210  func TestMultiProgressBarOrdering(t *testing.T) {
   211  	var in bytes.Buffer
   212  	var buf bytes.Buffer
   213  
   214  	progressBarElements := map[string]string{"1": "test1", "2": "test2", "3": "test3"}
   215  	multiprogress, err := newMultiProgressBarsMock(progressBarElements, []string{"1", "3", "2"}, &in, &buf)
   216  	require.NoError(t, err)
   217  
   218  	go func() {
   219  		// we need to wait for tea to start the Program, otherwise these would be no-ops
   220  		time.Sleep(1 * time.Millisecond)
   221  		multiprogress.OnProgress("1", 1.0)
   222  		multiprogress.OnProgress("2", 1.0)
   223  		multiprogress.OnProgress("3", 1.0)
   224  		multiprogress.Score("1", "F")
   225  		multiprogress.Completed("1")
   226  		multiprogress.Score("2", "F")
   227  		multiprogress.Completed("2")
   228  		multiprogress.Score("3", "F")
   229  		multiprogress.Completed("3")
   230  		multiprogress.Close()
   231  	}()
   232  	err = multiprogress.Open()
   233  	require.NoError(t, err)
   234  	assert.Contains(t, buf.String(), "test1                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% score: F")
   235  	assert.Contains(t, buf.String(), "test2                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% score: F")
   236  	assert.Contains(t, buf.String(), "test3                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% score: F")
   237  	assert.Contains(t, buf.String(), "3/3 scanned                     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100%")
   238  	// regexp is not working, perhaps because of ansi escape characters???
   239  	// ordering := regexp.MustCompile(`^.*test1.*test3.*test2.*$`)
   240  	// m := ordering.FindString(buf.String())
   241  	assert.Contains(t, buf.String(), "test1                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% score: F\r\n test3                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% score: F\r\n test2")
   242  }
   243  
   244  func TestMultiProgressBarNotApplicable(t *testing.T) {
   245  	var in bytes.Buffer
   246  	var buf bytes.Buffer
   247  
   248  	progressBarElements := map[string]string{"1": "test1", "2": "test2", "3": "test3"}
   249  	multiprogress, err := newMultiProgressBarsMock(progressBarElements, []string{"1", "2", "3"}, &in, &buf)
   250  	require.NoError(t, err)
   251  
   252  	go func() {
   253  		// we need to wait for tea to start the Program, otherwise these would be no-ops
   254  		time.Sleep(1 * time.Millisecond)
   255  		multiprogress.OnProgress("1", 1.0)
   256  		multiprogress.Score("1", "F")
   257  		multiprogress.Completed("1")
   258  
   259  		multiprogress.Score("2", "X")
   260  		multiprogress.Errored("2")
   261  
   262  		multiprogress.Score("3", "U")
   263  		multiprogress.NotApplicable("3")
   264  	}()
   265  	err = multiprogress.Open()
   266  	require.NoError(t, err)
   267  
   268  	assert.Contains(t, buf.String(), "test1                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% score: F")
   269  	assert.Contains(t, buf.String(), "test2                           ───────────────────────────────────    X score: X")
   270  	assert.Contains(t, buf.String(), "test3                           ───────────────────────────────────  n/a score: U")
   271  	assert.Contains(t, buf.String(), "1/3 scanned 1/3 errored 1/3 n/a ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100%")
   272  }