golang.org/x/playground@v0.0.0-20230418134305-14ebe15bcd59/sandbox/sandbox_test.go (about)

     1  // Copyright 2020 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package main
     6  
     7  import (
     8  	"bytes"
     9  	"io"
    10  	"strings"
    11  	"testing"
    12  	"testing/iotest"
    13  
    14  	"github.com/google/go-cmp/cmp"
    15  )
    16  
    17  func TestLimitedWriter(t *testing.T) {
    18  	cases := []struct {
    19  		desc          string
    20  		lw            *limitedWriter
    21  		in            []byte
    22  		want          []byte
    23  		wantN         int64
    24  		wantRemaining int64
    25  		err           error
    26  	}{
    27  		{
    28  			desc:          "simple",
    29  			lw:            &limitedWriter{dst: &bytes.Buffer{}, n: 10},
    30  			in:            []byte("hi"),
    31  			want:          []byte("hi"),
    32  			wantN:         2,
    33  			wantRemaining: 8,
    34  		},
    35  		{
    36  			desc:          "writing nothing",
    37  			lw:            &limitedWriter{dst: &bytes.Buffer{}, n: 10},
    38  			in:            []byte(""),
    39  			want:          []byte(""),
    40  			wantN:         0,
    41  			wantRemaining: 10,
    42  		},
    43  		{
    44  			desc:          "writing exactly enough",
    45  			lw:            &limitedWriter{dst: &bytes.Buffer{}, n: 6},
    46  			in:            []byte("enough"),
    47  			want:          []byte("enough"),
    48  			wantN:         6,
    49  			wantRemaining: 0,
    50  			err:           nil,
    51  		},
    52  		{
    53  			desc:          "writing too much",
    54  			lw:            &limitedWriter{dst: &bytes.Buffer{}, n: 10},
    55  			in:            []byte("this is much longer than 10"),
    56  			want:          []byte("this is mu"),
    57  			wantN:         10,
    58  			wantRemaining: -1,
    59  			err:           errTooMuchOutput,
    60  		},
    61  	}
    62  	for _, c := range cases {
    63  		t.Run(c.desc, func(t *testing.T) {
    64  			n, err := io.Copy(c.lw, iotest.OneByteReader(bytes.NewReader(c.in)))
    65  			if err != c.err {
    66  				t.Errorf("c.lw.Write(%q) = %d, %q, wanted %d, %q", c.in, n, err, c.wantN, c.err)
    67  			}
    68  			if n != c.wantN {
    69  				t.Errorf("c.lw.Write(%q) = %d, %q, wanted %d, %q", c.in, n, err, c.wantN, c.err)
    70  			}
    71  			if c.lw.n != c.wantRemaining {
    72  				t.Errorf("c.lw.n = %d, wanted %d", c.lw.n, c.wantRemaining)
    73  			}
    74  			if string(c.lw.dst.Bytes()) != string(c.want) {
    75  				t.Errorf("c.lw.dst.Bytes() = %q, wanted %q", c.lw.dst.Bytes(), c.want)
    76  			}
    77  		})
    78  	}
    79  }
    80  
    81  func TestSwitchWriter(t *testing.T) {
    82  	cases := []struct {
    83  		desc      string
    84  		sw        *switchWriter
    85  		in        []byte
    86  		want1     []byte
    87  		want2     []byte
    88  		wantN     int64
    89  		wantFound bool
    90  		err       error
    91  	}{
    92  		{
    93  			desc:      "not found",
    94  			sw:        &switchWriter{switchAfter: []byte("UNIQUE")},
    95  			in:        []byte("hi"),
    96  			want1:     []byte("hi"),
    97  			want2:     []byte(""),
    98  			wantN:     2,
    99  			wantFound: false,
   100  		},
   101  		{
   102  			desc:      "writing nothing",
   103  			sw:        &switchWriter{switchAfter: []byte("UNIQUE")},
   104  			in:        []byte(""),
   105  			want1:     []byte(""),
   106  			want2:     []byte(""),
   107  			wantN:     0,
   108  			wantFound: false,
   109  		},
   110  		{
   111  			desc:      "writing exactly switchAfter",
   112  			sw:        &switchWriter{switchAfter: []byte("UNIQUE")},
   113  			in:        []byte("UNIQUE"),
   114  			want1:     []byte("UNIQUE"),
   115  			want2:     []byte(""),
   116  			wantN:     6,
   117  			wantFound: true,
   118  		},
   119  		{
   120  			desc:      "writing before and after switchAfter",
   121  			sw:        &switchWriter{switchAfter: []byte("UNIQUE")},
   122  			in:        []byte("this is before UNIQUE and this is after"),
   123  			want1:     []byte("this is before UNIQUE"),
   124  			want2:     []byte(" and this is after"),
   125  			wantN:     39,
   126  			wantFound: true,
   127  		},
   128  	}
   129  	for _, c := range cases {
   130  		t.Run(c.desc, func(t *testing.T) {
   131  			dst1, dst2 := &bytes.Buffer{}, &bytes.Buffer{}
   132  			c.sw.dst1, c.sw.dst2 = dst1, dst2
   133  			n, err := io.Copy(c.sw, iotest.OneByteReader(bytes.NewReader(c.in)))
   134  			if err != c.err {
   135  				t.Errorf("c.sw.Write(%q) = %d, %q, wanted %d, %q", c.in, n, err, c.wantN, c.err)
   136  			}
   137  			if n != c.wantN {
   138  				t.Errorf("c.sw.Write(%q) = %d, %q, wanted %d, %q", c.in, n, err, c.wantN, c.err)
   139  			}
   140  			if c.sw.found != c.wantFound {
   141  				t.Errorf("c.sw.found = %v, wanted %v", c.sw.found, c.wantFound)
   142  			}
   143  			if string(dst1.Bytes()) != string(c.want1) {
   144  				t.Errorf("dst1.Bytes() = %q, wanted %q", dst1.Bytes(), c.want1)
   145  			}
   146  			if string(dst2.Bytes()) != string(c.want2) {
   147  				t.Errorf("dst2.Bytes() = %q, wanted %q", dst2.Bytes(), c.want2)
   148  			}
   149  		})
   150  	}
   151  }
   152  
   153  func TestSwitchWriterMultipleWrites(t *testing.T) {
   154  	dst1, dst2 := &bytes.Buffer{}, &bytes.Buffer{}
   155  	sw := &switchWriter{
   156  		dst1:        dst1,
   157  		dst2:        dst2,
   158  		switchAfter: []byte("GOPHER"),
   159  	}
   160  	n, err := io.Copy(sw, iotest.OneByteReader(strings.NewReader("this is before GO")))
   161  	if err != nil || n != 17 {
   162  		t.Errorf("sw.Write(%q) = %d, %q, wanted %d, no error", "this is before GO", n, err, 17)
   163  	}
   164  	if sw.found {
   165  		t.Errorf("sw.found = %v, wanted %v", sw.found, false)
   166  	}
   167  	if string(dst1.Bytes()) != "this is before GO" {
   168  		t.Errorf("dst1.Bytes() = %q, wanted %q", dst1.Bytes(), "this is before GO")
   169  	}
   170  	if string(dst2.Bytes()) != "" {
   171  		t.Errorf("dst2.Bytes() = %q, wanted %q", dst2.Bytes(), "")
   172  	}
   173  	n, err = io.Copy(sw, iotest.OneByteReader(strings.NewReader("PHER and this is after")))
   174  	if err != nil || n != 22 {
   175  		t.Errorf("sw.Write(%q) = %d, %q, wanted %d, no error", "this is before GO", n, err, 22)
   176  	}
   177  	if !sw.found {
   178  		t.Errorf("sw.found = %v, wanted %v", sw.found, true)
   179  	}
   180  	if string(dst1.Bytes()) != "this is before GOPHER" {
   181  		t.Errorf("dst1.Bytes() = %q, wanted %q", dst1.Bytes(), "this is before GOPHEr")
   182  	}
   183  	if string(dst2.Bytes()) != " and this is after" {
   184  		t.Errorf("dst2.Bytes() = %q, wanted %q", dst2.Bytes(), " and this is after")
   185  	}
   186  }
   187  
   188  func TestParseDockerContainers(t *testing.T) {
   189  	cases := []struct {
   190  		desc    string
   191  		output  string
   192  		want    []dockerContainer
   193  		wantErr bool
   194  	}{
   195  		{
   196  			desc: "normal output (container per line)",
   197  			output: `{"Command":"\"/usr/local/bin/play…\"","CreatedAt":"2020-04-23 17:44:02 -0400 EDT","ID":"f7f170fde076","Image":"gcr.io/golang-org/playground-sandbox-gvisor:latest","Labels":"","LocalVolumes":"0","Mounts":"","Names":"play_run_a02cfe67","Networks":"none","Ports":"","RunningFor":"8 seconds ago","Size":"0B","Status":"Up 7 seconds"}
   198  {"Command":"\"/usr/local/bin/play…\"","CreatedAt":"2020-04-23 17:44:02 -0400 EDT","ID":"af872e55a773","Image":"gcr.io/golang-org/playground-sandbox-gvisor:latest","Labels":"","LocalVolumes":"0","Mounts":"","Names":"play_run_0a69c3e8","Networks":"none","Ports":"","RunningFor":"8 seconds ago","Size":"0B","Status":"Up 7 seconds"}`,
   199  			want: []dockerContainer{
   200  				{ID: "f7f170fde076", Image: "gcr.io/golang-org/playground-sandbox-gvisor:latest", Names: "play_run_a02cfe67"},
   201  				{ID: "af872e55a773", Image: "gcr.io/golang-org/playground-sandbox-gvisor:latest", Names: "play_run_0a69c3e8"},
   202  			},
   203  			wantErr: false,
   204  		},
   205  		{
   206  			desc:    "empty output",
   207  			wantErr: false,
   208  		},
   209  		{
   210  			desc:    "malformatted output",
   211  			output:  `xyzzy{}`,
   212  			wantErr: true,
   213  		},
   214  	}
   215  	for _, tc := range cases {
   216  		t.Run(tc.desc, func(t *testing.T) {
   217  			cs, err := parseDockerContainers([]byte(tc.output))
   218  			if (err != nil) != tc.wantErr {
   219  				t.Errorf("parseDockerContainers(_) = %v, %v, wantErr: %v", cs, err, tc.wantErr)
   220  			}
   221  			if diff := cmp.Diff(tc.want, cs); diff != "" {
   222  				t.Errorf("parseDockerContainers() mismatch (-want +got):\n%s", diff)
   223  			}
   224  		})
   225  	}
   226  }