...

Source file src/github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/exec_wcow_podsandbox_test.go

Documentation: github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1

     1  //go:build windows
     2  
     3  package main
     4  
     5  import (
     6  	"context"
     7  	"testing"
     8  	"time"
     9  
    10  	containerd_v1_types "github.com/containerd/containerd/api/types/task"
    11  	"github.com/containerd/containerd/errdefs"
    12  	"github.com/containerd/containerd/runtime/v2/task"
    13  	"github.com/pkg/errors"
    14  )
    15  
    16  func verifyWcowPodSandboxExecStatus(t *testing.T, wasStarted bool, es containerd_v1_types.Status, status *task.StateResponse) {
    17  	t.Helper()
    18  	if status.ID != t.Name() {
    19  		t.Fatalf("expected id: '%s' got: '%s'", t.Name(), status.ID)
    20  	}
    21  	if status.ExecID != t.Name() {
    22  		t.Fatalf("expected execid: '%s' got: '%s'", t.Name(), status.ExecID)
    23  	}
    24  	if status.Bundle != t.Name() {
    25  		t.Fatalf("expected bundle: '%s' got: '%s'", t.Name(), status.Bundle)
    26  	}
    27  	var expectedPid uint32
    28  	if wasStarted && es != containerd_v1_types.StatusCreated {
    29  		expectedPid = 1
    30  	}
    31  	if status.Pid != expectedPid {
    32  		t.Fatalf("expected pid: '%d' got: '%d'", expectedPid, status.Pid)
    33  	}
    34  	if status.Status != es {
    35  		t.Fatalf("expected status: '%s' got: '%s'", es, status.Status)
    36  	}
    37  	if status.Stdin != "" {
    38  		t.Fatalf("expected stdin: '' got: '%s'", status.Stdin)
    39  	}
    40  	if status.Stdout != "" {
    41  		t.Fatalf("expected stdout: '' got: '%s'", status.Stdout)
    42  	}
    43  	if status.Stderr != "" {
    44  		t.Fatalf("expected stderr: '' got: '%s'", status.Stderr)
    45  	}
    46  	if status.Terminal {
    47  		t.Fatalf("expected terminal: 'false' got: '%v'", status.Terminal)
    48  	}
    49  	var expectedExitStatus uint32
    50  	switch es {
    51  	case containerd_v1_types.StatusCreated, containerd_v1_types.StatusRunning:
    52  		expectedExitStatus = 255
    53  	case containerd_v1_types.StatusStopped:
    54  		if !wasStarted {
    55  			expectedExitStatus = 1
    56  		} else {
    57  			expectedExitStatus = 0
    58  		}
    59  	}
    60  	if status.ExitStatus != expectedExitStatus {
    61  		t.Fatalf("expected exitstatus: '%d' got: '%d'", expectedExitStatus, status.ExitStatus)
    62  	}
    63  	if es != containerd_v1_types.StatusStopped {
    64  		if !status.ExitedAt.IsZero() {
    65  			t.Fatalf("expected exitedat: '%v' got: '%v'", time.Time{}, status.ExitedAt)
    66  		}
    67  	} else {
    68  		if status.ExitedAt.IsZero() {
    69  			t.Fatalf("expected exitedat: > '%v' got: '%v'", time.Time{}, status.ExitedAt)
    70  		}
    71  	}
    72  }
    73  
    74  func Test_newWcowPodSandboxExec(t *testing.T) {
    75  	wpse := newWcowPodSandboxExec(context.TODO(), newFakePublisher(), t.Name(), t.Name())
    76  
    77  	verifyWcowPodSandboxExecStatus(t, false, containerd_v1_types.StatusCreated, wpse.Status())
    78  }
    79  
    80  func Test_newWcowPodSandboxExec_ID(t *testing.T) {
    81  	wpse := newWcowPodSandboxExec(context.TODO(), newFakePublisher(), t.Name(), t.Name())
    82  
    83  	if wpse.ID() != t.Name() {
    84  		t.Fatalf("expected ID: '%s' got: '%s", t.Name(), wpse.ID())
    85  	}
    86  }
    87  
    88  func Test_newWcowPodSandboxExec_Pid(t *testing.T) {
    89  	wpse := newWcowPodSandboxExec(context.TODO(), newFakePublisher(), t.Name(), t.Name())
    90  
    91  	if wpse.Pid() != 0 {
    92  		t.Fatalf("expected created pid: '0' got: '%d", wpse.Pid())
    93  	}
    94  
    95  	// Start it
    96  	err := wpse.Start(context.TODO())
    97  	if err != nil {
    98  		t.Fatalf("should not have failed to start got: %v", err)
    99  	}
   100  
   101  	if wpse.Pid() != 1 {
   102  		t.Fatalf("expected running pid: '1' got: '%d", wpse.Pid())
   103  	}
   104  
   105  	// Stop it
   106  	err = wpse.Kill(context.TODO(), 0x0)
   107  	if err != nil {
   108  		t.Fatalf("should not have failed to stop got: %v", err)
   109  	}
   110  
   111  	if wpse.Pid() != 1 {
   112  		t.Fatalf("expected stopped pid: '1' got: '%d", wpse.Pid())
   113  	}
   114  }
   115  
   116  func Test_newWcowPodSandboxExec_State(t *testing.T) {
   117  	wpse := newWcowPodSandboxExec(context.TODO(), newFakePublisher(), t.Name(), t.Name())
   118  
   119  	if wpse.State() != shimExecStateCreated {
   120  		t.Fatalf("expected state: '%s' got: '%s", shimExecStateCreated, wpse.State())
   121  	}
   122  
   123  	// Start it
   124  	err := wpse.Start(context.TODO())
   125  	if err != nil {
   126  		t.Fatalf("should not have failed to start got: %v", err)
   127  	}
   128  
   129  	if wpse.State() != shimExecStateRunning {
   130  		t.Fatalf("expected state: '%s' got: '%s", shimExecStateRunning, wpse.State())
   131  	}
   132  
   133  	// Stop it
   134  	err = wpse.Kill(context.TODO(), 0x0)
   135  	if err != nil {
   136  		t.Fatalf("should not have failed to stop got: %v", err)
   137  	}
   138  
   139  	if wpse.State() != shimExecStateExited {
   140  		t.Fatalf("expected state: '%s' got: '%s", shimExecStateExited, wpse.State())
   141  	}
   142  }
   143  
   144  func Test_newWcowPodSandboxExec_Status(t *testing.T) {
   145  	wpse := newWcowPodSandboxExec(context.TODO(), newFakePublisher(), t.Name(), t.Name())
   146  
   147  	verifyWcowPodSandboxExecStatus(t, false, containerd_v1_types.StatusCreated, wpse.Status())
   148  
   149  	// Start it
   150  	err := wpse.Start(context.TODO())
   151  	if err != nil {
   152  		t.Fatalf("should not have failed to start got: %v", err)
   153  	}
   154  
   155  	verifyWcowPodSandboxExecStatus(t, true, containerd_v1_types.StatusRunning, wpse.Status())
   156  
   157  	// Stop it
   158  	err = wpse.Kill(context.TODO(), 0x0)
   159  	if err != nil {
   160  		t.Fatalf("should not have failed to stop got: %v", err)
   161  	}
   162  
   163  	verifyWcowPodSandboxExecStatus(t, true, containerd_v1_types.StatusStopped, wpse.Status())
   164  }
   165  
   166  func Test_newWcowPodSandboxExec_Start(t *testing.T) {
   167  	wpse := newWcowPodSandboxExec(context.TODO(), newFakePublisher(), t.Name(), t.Name())
   168  
   169  	// Start it
   170  	err := wpse.Start(context.TODO())
   171  	if err != nil {
   172  		t.Fatalf("should not have failed to start got: %v", err)
   173  	}
   174  	if wpse.State() != shimExecStateRunning {
   175  		t.Fatalf("should of transitioned to running state")
   176  	}
   177  
   178  	// Call start again
   179  	err = wpse.Start(context.TODO())
   180  	verifyExpectedError(t, nil, err, errdefs.ErrFailedPrecondition)
   181  }
   182  
   183  func Test_newWcowPodSandboxExec_Kill_Created(t *testing.T) {
   184  	wpse := newWcowPodSandboxExec(context.TODO(), newFakePublisher(), t.Name(), t.Name())
   185  
   186  	// Kill it in the created state
   187  	err := wpse.Kill(context.TODO(), 0x0)
   188  	if err != nil {
   189  		t.Fatalf("should not have failed to kill got: %v", err)
   190  	}
   191  	if wpse.State() != shimExecStateExited {
   192  		t.Fatalf("should of transitioned to exited state")
   193  	}
   194  
   195  	// Call Kill again
   196  	err = wpse.Kill(context.TODO(), 0x0)
   197  	if errors.Cause(err) != errdefs.ErrNotFound {
   198  		t.Fatalf("Kill should fail with `ErrNotFound` in the exited state got: %v", err)
   199  	}
   200  }
   201  
   202  func Test_newWcowPodSandboxExec_Kill_Started(t *testing.T) {
   203  	wpse := newWcowPodSandboxExec(context.TODO(), newFakePublisher(), t.Name(), t.Name())
   204  
   205  	// Start it
   206  	err := wpse.Start(context.TODO())
   207  	if err != nil {
   208  		t.Fatalf("should not have failed to start got: %v", err)
   209  	}
   210  
   211  	// Kill it in the started state
   212  	err = wpse.Kill(context.TODO(), 0x0)
   213  	if err != nil {
   214  		t.Fatalf("should not have failed to kill got: %v", err)
   215  	}
   216  	if wpse.State() != shimExecStateExited {
   217  		t.Fatalf("should of transitioned to exited state")
   218  	}
   219  
   220  	// Call Kill again
   221  	err = wpse.Kill(context.TODO(), 0x0)
   222  	if errors.Cause(err) != errdefs.ErrNotFound {
   223  		t.Fatalf("Kill should fail with `ErrNotFound` in the exited state got: %v", err)
   224  	}
   225  }
   226  
   227  func Test_newWcowPodSandboxExec_ResizePty(t *testing.T) {
   228  	wpse := newWcowPodSandboxExec(context.TODO(), newFakePublisher(), t.Name(), t.Name())
   229  
   230  	// Resize in created state
   231  	err := wpse.ResizePty(context.TODO(), 10, 10)
   232  	verifyExpectedError(t, nil, err, errdefs.ErrFailedPrecondition)
   233  
   234  	// Start it
   235  	err = wpse.Start(context.TODO())
   236  	if err != nil {
   237  		t.Fatalf("should not have failed to start got: %v", err)
   238  	}
   239  
   240  	err = wpse.ResizePty(context.TODO(), 10, 10)
   241  	verifyExpectedError(t, nil, err, errdefs.ErrFailedPrecondition)
   242  
   243  	// Stop it
   244  	err = wpse.Kill(context.TODO(), 0x0)
   245  	if err != nil {
   246  		t.Fatalf("should not have failed to stop got: %v", err)
   247  	}
   248  
   249  	err = wpse.ResizePty(context.TODO(), 10, 10)
   250  	verifyExpectedError(t, nil, err, errdefs.ErrFailedPrecondition)
   251  }
   252  
   253  func Test_newWcowPodSandboxExec_CloseIO(t *testing.T) {
   254  	wpse := newWcowPodSandboxExec(context.TODO(), newFakePublisher(), t.Name(), t.Name())
   255  
   256  	// Resize in created state
   257  	err := wpse.CloseIO(context.TODO(), true)
   258  	if err != nil {
   259  		t.Fatalf("should not have failed CloseIO in created state got: %v", err)
   260  	}
   261  
   262  	// Start it
   263  	err = wpse.Start(context.TODO())
   264  	if err != nil {
   265  		t.Fatalf("should not have failed to start got: %v", err)
   266  	}
   267  
   268  	err = wpse.CloseIO(context.TODO(), true)
   269  	if err != nil {
   270  		t.Fatalf("should not have failed CloseIO in running state got: %v", err)
   271  	}
   272  
   273  	// Stop it
   274  	err = wpse.Kill(context.TODO(), 0x0)
   275  	if err != nil {
   276  		t.Fatalf("should not have failed to stop got: %v", err)
   277  	}
   278  
   279  	err = wpse.CloseIO(context.TODO(), true)
   280  	if err != nil {
   281  		t.Fatalf("should not have failed CloseIO in exited state got: %v", err)
   282  	}
   283  }
   284  
   285  func Test_newWcowPodSandboxExec_Wait_Created(t *testing.T) {
   286  	wpse := newWcowPodSandboxExec(context.TODO(), newFakePublisher(), t.Name(), t.Name())
   287  
   288  	waitExit := make(chan *task.StateResponse, 1)
   289  	defer close(waitExit)
   290  
   291  	// Issue the wait in the created state
   292  	go func() {
   293  		waitExit <- wpse.Wait()
   294  	}()
   295  
   296  	now := time.Now()
   297  	err := wpse.Kill(context.TODO(), 0x0)
   298  	if err != nil {
   299  		t.Fatalf("should not have failed to kill got: %v", err)
   300  	}
   301  
   302  	status := <-waitExit
   303  	verifyWcowPodSandboxExecStatus(t, false, containerd_v1_types.StatusStopped, status)
   304  	if status.ExitedAt.Before(now) {
   305  		t.Fatal("exit should not have unblocked previous to kill")
   306  	}
   307  
   308  	// Verify the wait in the exited state doesnt block.
   309  	verifyWcowPodSandboxExecStatus(t, false, containerd_v1_types.StatusStopped, wpse.Wait())
   310  }
   311  
   312  func Test_newWcowPodSandboxExec_Wait_Started(t *testing.T) {
   313  	wpse := newWcowPodSandboxExec(context.TODO(), newFakePublisher(), t.Name(), t.Name())
   314  
   315  	waitExit := make(chan *task.StateResponse, 1)
   316  	defer close(waitExit)
   317  
   318  	// Issue the wait in the created state
   319  	go func() {
   320  		waitExit <- wpse.Wait()
   321  	}()
   322  
   323  	err := wpse.Start(context.TODO())
   324  	if err != nil {
   325  		t.Fatalf("should not have failed to start got: %v", err)
   326  	}
   327  
   328  	now := time.Now()
   329  	err = wpse.Kill(context.TODO(), 0x0)
   330  	if err != nil {
   331  		t.Fatalf("should not have failed to kill got: %v", err)
   332  	}
   333  
   334  	status := <-waitExit
   335  	verifyWcowPodSandboxExecStatus(t, true, containerd_v1_types.StatusStopped, status)
   336  	if status.ExitedAt.Before(now) {
   337  		t.Fatal("exit should not have unblocked previous to kill")
   338  	}
   339  
   340  	// Verify the wait in the exited state doesnt block.
   341  	verifyWcowPodSandboxExecStatus(t, true, containerd_v1_types.StatusStopped, wpse.Wait())
   342  }
   343  

View as plain text