...

Source file src/github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/task_hcs_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  	"math/rand"
     8  	"strconv"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/containerd/containerd/errdefs"
    13  )
    14  
    15  func setupTestHcsTask(t *testing.T) (*hcsTask, *testShimExec, *testShimExec) {
    16  	t.Helper()
    17  	initExec := newTestShimExec(t.Name(), t.Name(), int(rand.Int31()))
    18  	lt := &hcsTask{
    19  		events: newFakePublisher(),
    20  		id:     t.Name(),
    21  		init:   initExec,
    22  		closed: make(chan struct{}),
    23  	}
    24  	secondExecID := strconv.Itoa(rand.Int())
    25  	secondExec := newTestShimExec(t.Name(), secondExecID, int(rand.Int31()))
    26  	lt.execs.Store(secondExecID, secondExec)
    27  	return lt, initExec, secondExec
    28  }
    29  
    30  func Test_hcsTask_ID(t *testing.T) {
    31  	lt, _, _ := setupTestHcsTask(t)
    32  
    33  	if lt.ID() != t.Name() {
    34  		t.Fatalf("expect ID: '%s', got: '%s'", t.Name(), lt.ID())
    35  	}
    36  }
    37  
    38  func Test_hcsTask_GetExec_Empty_Success(t *testing.T) {
    39  	lt, i, _ := setupTestHcsTask(t)
    40  
    41  	e, err := lt.GetExec("")
    42  	if err != nil {
    43  		t.Fatalf("should not have failed with error: %v", err)
    44  	}
    45  	if i != e {
    46  		t.Fatal("should of returned the init exec on empty")
    47  	}
    48  }
    49  
    50  func Test_hcsTask_GetExec_UnknownExecID_Error(t *testing.T) {
    51  	lt, _, _ := setupTestHcsTask(t)
    52  
    53  	e, err := lt.GetExec("shouldnotmatch")
    54  
    55  	verifyExpectedError(t, e, err, errdefs.ErrNotFound)
    56  }
    57  
    58  func Test_hcsTask_GetExec_2ndID_Success(t *testing.T) {
    59  	lt, _, second := setupTestHcsTask(t)
    60  
    61  	e, err := lt.GetExec(second.id)
    62  	if err != nil {
    63  		t.Fatalf("should not have failed with error: %v", err)
    64  	}
    65  	if second != e {
    66  		t.Fatal("should of returned the second exec")
    67  	}
    68  }
    69  
    70  func Test_hcsTask_KillExec_UnknownExecID_Error(t *testing.T) {
    71  	lt, _, _ := setupTestHcsTask(t)
    72  
    73  	err := lt.KillExec(context.TODO(), "thisshouldnotmatch", 0xf, false)
    74  
    75  	verifyExpectedError(t, nil, err, errdefs.ErrNotFound)
    76  }
    77  
    78  func Test_hcsTask_KillExec_InitExecID_Unexited2ndExec_Success(t *testing.T) {
    79  	lt, init, second := setupTestHcsTask(t)
    80  
    81  	err := lt.KillExec(context.TODO(), "", 0xf, false)
    82  	if err != nil {
    83  		t.Fatalf("should not have failed, got: %v", err)
    84  	}
    85  	if init.state != shimExecStateExited {
    86  		t.Fatalf("init should be in exited state got: %v", init.state)
    87  	}
    88  	// A real platform would take this down when the pid namespace or silo goes
    89  	// down. For the test verify the shim did not issue the signal.
    90  	if second.state != shimExecStateCreated {
    91  		t.Fatalf("2nd exec should be in created state, got: %v", second.state)
    92  	}
    93  }
    94  
    95  func Test_hcsTask_KillExec_InitExecID_All_Success(t *testing.T) {
    96  	lt, init, second := setupTestHcsTask(t)
    97  
    98  	err := lt.KillExec(context.TODO(), "", 0xf, true)
    99  	if err != nil {
   100  		t.Fatalf("should not have failed, got: %v", err)
   101  	}
   102  	if init.state != shimExecStateExited {
   103  		t.Fatalf("init should be in exited state got: %v", init.state)
   104  	}
   105  	if second.state != shimExecStateExited {
   106  		t.Fatalf("2nd exec should be in exited state got: %v", second.state)
   107  	}
   108  }
   109  
   110  func Test_hcsTask_KillExec_2ndExecID_Success(t *testing.T) {
   111  	lt, _, second := setupTestHcsTask(t)
   112  
   113  	err := lt.KillExec(context.TODO(), second.id, 0xf, false)
   114  	if err != nil {
   115  		t.Fatalf("should not have failed, got: %v", err)
   116  	}
   117  	if second.state != shimExecStateExited {
   118  		t.Fatalf("2nd exec should be in exited state got: %v", second.state)
   119  	}
   120  }
   121  
   122  func Test_hcsTask_KillExec_2ndExecID_All_Error(t *testing.T) {
   123  	lt, _, second := setupTestHcsTask(t)
   124  
   125  	err := lt.KillExec(context.TODO(), second.id, 0xf, true)
   126  
   127  	verifyExpectedError(t, nil, err, errdefs.ErrFailedPrecondition)
   128  }
   129  
   130  func verifyDeleteFailureValues(t *testing.T, pid int, status uint32, at time.Time) {
   131  	t.Helper()
   132  	if pid != 0 {
   133  		t.Fatalf("pid expected '0' got: '%d'", pid)
   134  	}
   135  	if status != 0 {
   136  		t.Fatalf("status expected '0' got: '%d'", status)
   137  	}
   138  	if !at.IsZero() {
   139  		t.Fatalf("at expected 'zero' got: '%v'", at)
   140  	}
   141  }
   142  
   143  func verifyDeleteSuccessValues(t *testing.T, pid int, status uint32, at time.Time, e *testShimExec) {
   144  	t.Helper()
   145  	if pid != e.pid {
   146  		t.Fatalf("pid expected '%d' got: '%d'", e.pid, pid)
   147  	}
   148  	if status != e.status {
   149  		t.Fatalf("status expected '%d' got: '%d'", e.status, status)
   150  	}
   151  	if at != e.at {
   152  		t.Fatalf("at expected '%v' got: '%v'", e.at, at)
   153  	}
   154  }
   155  
   156  func Test_hcsTask_DeleteExec_UnknownExecID_Error(t *testing.T) {
   157  	lt, _, _ := setupTestHcsTask(t)
   158  
   159  	pid, status, at, err := lt.DeleteExec(context.TODO(), "thisshouldnotmatch")
   160  	verifyExpectedError(t, nil, err, errdefs.ErrNotFound)
   161  	verifyDeleteFailureValues(t, pid, status, at)
   162  }
   163  
   164  func Test_hcsTask_DeleteExec_InitExecID_CreatedState_Success(t *testing.T) {
   165  	lt, init, second := setupTestHcsTask(t)
   166  	// remove the 2nd exec so we just check without it.
   167  	lt.execs.Delete(second.id)
   168  
   169  	// Simulate waitInitExit() closing the host
   170  	close(lt.closed)
   171  	// try to delete the init exec
   172  	pid, status, at, err := lt.DeleteExec(context.TODO(), "")
   173  
   174  	if err != nil {
   175  		t.Fatalf("expected nil err got: %v", err)
   176  	}
   177  	verifyDeleteSuccessValues(t, pid, status, at, init)
   178  }
   179  
   180  func Test_hcsTask_DeleteExec_InitExecID_RunningState_Error(t *testing.T) {
   181  	lt, init, second := setupTestHcsTask(t)
   182  	// remove the 2nd exec so we just check without it.
   183  	lt.execs.Delete(second.id)
   184  
   185  	// Start the init exec
   186  	_ = init.Start(context.TODO())
   187  
   188  	// Simulate waitInitExit() closing the host
   189  	close(lt.closed)
   190  	// try to delete the init exec
   191  	pid, status, at, err := lt.DeleteExec(context.TODO(), "")
   192  
   193  	verifyExpectedError(t, nil, err, errdefs.ErrFailedPrecondition)
   194  	verifyDeleteFailureValues(t, pid, status, at)
   195  }
   196  
   197  func Test_hcsTask_DeleteExec_InitExecID_ExitedState_Success(t *testing.T) {
   198  	lt, init, second := setupTestHcsTask(t)
   199  	// remove the 2nd exec so we just check without it.
   200  	lt.execs.Delete(second.id)
   201  
   202  	_ = init.Kill(context.TODO(), 0xf)
   203  
   204  	// Simulate waitInitExit() closing the host
   205  	close(lt.closed)
   206  	// try to delete the init exec
   207  	pid, status, at, err := lt.DeleteExec(context.TODO(), "")
   208  
   209  	if err != nil {
   210  		t.Fatalf("expected nil err got: %v", err)
   211  	}
   212  	verifyDeleteSuccessValues(t, pid, status, at, init)
   213  }
   214  
   215  func Test_hcsTask_DeleteExec_InitExecID_2ndExec_CreatedState_Error(t *testing.T) {
   216  	lt, init, second := setupTestHcsTask(t)
   217  
   218  	// start the init exec (required to have 2nd exec)
   219  	_ = init.Start(context.TODO())
   220  
   221  	// Simulate waitInitExit() closing the host
   222  	close(lt.closed)
   223  	// try to delete the init exec
   224  	pid, status, at, err := lt.DeleteExec(context.TODO(), "")
   225  
   226  	verifyExpectedError(t, nil, err, errdefs.ErrFailedPrecondition)
   227  	verifyDeleteFailureValues(t, pid, status, at)
   228  	if second.state != shimExecStateExited {
   229  		t.Fatalf("2nd exec should be in exited state, got: %v", second.state)
   230  	}
   231  }
   232  
   233  func Test_hcsTask_DeleteExec_InitExecID_2ndExec_RunningState_Error(t *testing.T) {
   234  	lt, init, second := setupTestHcsTask(t)
   235  
   236  	// start the init exec (required to have 2nd exec)
   237  	_ = init.Start(context.TODO())
   238  
   239  	// put the 2nd exec into the running state
   240  	_ = second.Start(context.TODO())
   241  
   242  	// Simulate waitInitExit() closing the host
   243  	close(lt.closed)
   244  	// try to delete the init exec
   245  	pid, status, at, err := lt.DeleteExec(context.TODO(), "")
   246  
   247  	verifyExpectedError(t, nil, err, errdefs.ErrFailedPrecondition)
   248  	verifyDeleteFailureValues(t, pid, status, at)
   249  	if second.state != shimExecStateExited {
   250  		t.Fatalf("2nd exec should be in exited state, got: %v", second.state)
   251  	}
   252  }
   253  
   254  func Test_hcsTask_DeleteExec_InitExecID_2ndExec_ExitedState_Success(t *testing.T) {
   255  	lt, init, second := setupTestHcsTask(t)
   256  
   257  	// put the init exec into the exited state
   258  	_ = init.Kill(context.TODO(), 0xf)
   259  	// put the 2nd exec into the exited state
   260  	_ = second.Kill(context.TODO(), 0xf)
   261  
   262  	// Simulate waitInitExit() closing the host
   263  	close(lt.closed)
   264  	// try to delete the init exec
   265  	pid, status, at, err := lt.DeleteExec(context.TODO(), "")
   266  
   267  	if err != nil {
   268  		t.Fatalf("expected nil err got: %v", err)
   269  	}
   270  	verifyDeleteSuccessValues(t, pid, status, at, init)
   271  }
   272  
   273  func Test_hcsTask_DeleteExec_2ndExecID_CreatedState_Success(t *testing.T) {
   274  	lt, init, second := setupTestHcsTask(t)
   275  
   276  	// start the init exec (required to have 2nd exec)
   277  	_ = init.Start(context.TODO())
   278  
   279  	// try to delete the 2nd exec
   280  	pid, status, at, err := lt.DeleteExec(context.TODO(), second.id)
   281  
   282  	if err != nil {
   283  		t.Fatalf("expected nil err got: %v", err)
   284  	}
   285  	verifyDeleteSuccessValues(t, pid, status, at, second)
   286  }
   287  
   288  func Test_hcsTask_DeleteExec_2ndExecID_RunningState_Error(t *testing.T) {
   289  	lt, init, second := setupTestHcsTask(t)
   290  
   291  	// start the init exec (required to have 2nd exec)
   292  	_ = init.Start(context.TODO())
   293  
   294  	// put the 2nd exec into the running state
   295  	_ = second.Start(context.TODO())
   296  
   297  	// try to delete the 2nd exec
   298  	pid, status, at, err := lt.DeleteExec(context.TODO(), second.id)
   299  
   300  	verifyExpectedError(t, nil, err, errdefs.ErrFailedPrecondition)
   301  	verifyDeleteFailureValues(t, pid, status, at)
   302  }
   303  
   304  func Test_hcsTask_DeleteExec_2ndExecID_ExitedState_Success(t *testing.T) {
   305  	lt, init, second := setupTestHcsTask(t)
   306  
   307  	// start the init exec (required to have 2nd exec)
   308  	_ = init.Kill(context.TODO(), 0xf)
   309  
   310  	// put the 2nd exec into the exited state
   311  	_ = second.Kill(context.TODO(), 0xf)
   312  
   313  	// try to delete the 2nd exec
   314  	pid, status, at, err := lt.DeleteExec(context.TODO(), second.id)
   315  
   316  	if err != nil {
   317  		t.Fatalf("expected nil err got: %v", err)
   318  	}
   319  	verifyDeleteSuccessValues(t, pid, status, at, second)
   320  }
   321  

View as plain text