...

Source file src/github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/pod_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  	"fmt"
     8  	"math/rand"
     9  	"strconv"
    10  	"sync"
    11  	"testing"
    12  
    13  	"github.com/containerd/containerd/errdefs"
    14  	"github.com/containerd/containerd/runtime/v2/task"
    15  	specs "github.com/opencontainers/runtime-spec/specs-go"
    16  )
    17  
    18  var _ = (shimPod)(&testShimPod{})
    19  
    20  type testShimPod struct {
    21  	id string
    22  
    23  	tasks sync.Map
    24  }
    25  
    26  func (tsp *testShimPod) ID() string {
    27  	return tsp.id
    28  }
    29  
    30  func (tsp *testShimPod) CreateTask(ctx context.Context, req *task.CreateTaskRequest, s *specs.Spec) (shimTask, error) {
    31  	return nil, errdefs.ErrNotImplemented
    32  }
    33  
    34  func (tsp *testShimPod) GetTask(tid string) (shimTask, error) {
    35  	v, loaded := tsp.tasks.Load(tid)
    36  	if loaded {
    37  		return v.(shimTask), nil
    38  	}
    39  	return nil, errdefs.ErrNotFound
    40  }
    41  
    42  func (tsp *testShimPod) ListTasks() (_ []shimTask, err error) {
    43  	var tasks []shimTask
    44  	tsp.tasks.Range(func(key, value interface{}) bool {
    45  		wt, ok := value.(shimTask)
    46  		if !ok {
    47  			err = fmt.Errorf("failed to load tasks %s", key)
    48  			return false
    49  		}
    50  		tasks = append(tasks, wt)
    51  		return true
    52  	})
    53  	if err != nil {
    54  		return nil, err
    55  	}
    56  	return tasks, nil
    57  }
    58  
    59  func (tsp *testShimPod) KillTask(ctx context.Context, tid, eid string, signal uint32, all bool) error {
    60  	s, err := tsp.GetTask(tid)
    61  	if err != nil {
    62  		return err
    63  	}
    64  	return s.KillExec(ctx, eid, signal, all)
    65  }
    66  
    67  func (tsp *testShimPod) DeleteTask(ctx context.Context, tid string) error {
    68  	t, err := tsp.GetTask(tid)
    69  	if err != nil {
    70  		return err
    71  	}
    72  
    73  	e, err := t.GetExec("")
    74  	if err != nil {
    75  		return err
    76  	}
    77  	switch e.State() {
    78  	case shimExecStateRunning:
    79  		return errdefs.ErrFailedPrecondition
    80  	default:
    81  	}
    82  
    83  	if tid != tsp.ID() {
    84  		tsp.tasks.Delete(tid)
    85  	}
    86  	return nil
    87  }
    88  
    89  // Pod tests
    90  
    91  func setupTestPodWithFakes(t *testing.T) (*pod, *testShimTask) {
    92  	t.Helper()
    93  	st := &testShimTask{
    94  		id:    t.Name(),
    95  		exec:  newTestShimExec(t.Name(), t.Name(), 10),
    96  		execs: make(map[string]*testShimExec),
    97  	}
    98  	// Add a 2nd exec
    99  	seid := strconv.Itoa(rand.Int())
   100  	st.execs[seid] = newTestShimExec(t.Name(), seid, int(rand.Int31()))
   101  	p := &pod{
   102  		id:          t.Name(),
   103  		sandboxTask: st,
   104  	}
   105  	return p, st
   106  }
   107  
   108  func setupTestTaskInPod(t *testing.T, p *pod) *testShimTask {
   109  	t.Helper()
   110  	tid := strconv.Itoa(rand.Int())
   111  	wt := &testShimTask{
   112  		id:   tid,
   113  		exec: newTestShimExec(tid, tid, int(rand.Int31())),
   114  	}
   115  	p.workloadTasks.Store(wt.id, wt)
   116  	return wt
   117  }
   118  
   119  func Test_pod_ID(t *testing.T) {
   120  	p := pod{id: t.Name()}
   121  	id := p.ID()
   122  	if id != t.Name() {
   123  		t.Fatalf("pod should of returned ID: %s, got: %s", t.Name(), id)
   124  	}
   125  }
   126  
   127  func Test_pod_GetTask_SandboxID(t *testing.T) {
   128  	p, st := setupTestPodWithFakes(t)
   129  	t1, err := p.GetTask(t.Name())
   130  	if err != nil {
   131  		t.Fatalf("should not have failed, got: %v", err)
   132  	}
   133  	if t1 != st {
   134  		t.Fatal("should have returned sandbox task")
   135  	}
   136  }
   137  
   138  func Test_pod_GetTask_WorkloadID_NotCreated_Error(t *testing.T) {
   139  	p, _ := setupTestPodWithFakes(t)
   140  	t1, err := p.GetTask("thisshouldnotmatch")
   141  
   142  	verifyExpectedError(t, t1, err, errdefs.ErrNotFound)
   143  }
   144  
   145  func Test_pod_GetTask_WorkloadID_Created_Success(t *testing.T) {
   146  	p, _ := setupTestPodWithFakes(t)
   147  	t2 := setupTestTaskInPod(t, p)
   148  
   149  	resp, err := p.GetTask(t2.ID())
   150  	if err != nil {
   151  		t.Fatalf("should not have failed, got: %v", err)
   152  	}
   153  	if resp != t2 {
   154  		t.Fatal("should have returned workload task")
   155  	}
   156  }
   157  
   158  // kill tests
   159  
   160  func Test_pod_KillTask_UnknownTaskID_Error(t *testing.T) {
   161  	p, _ := setupTestPodWithFakes(t)
   162  	err := p.KillTask(context.TODO(), "thisshouldnotmatch", "", 0xf, false)
   163  
   164  	verifyExpectedError(t, nil, err, errdefs.ErrNotFound)
   165  }
   166  
   167  func Test_pod_KillTask_SandboxID_UnknownExecID_Error(t *testing.T) {
   168  	p, _ := setupTestPodWithFakes(t)
   169  	err := p.KillTask(context.TODO(), t.Name(), "thisshouldnotmatch", 0xf, false)
   170  
   171  	verifyExpectedError(t, nil, err, errdefs.ErrNotFound)
   172  }
   173  
   174  func Test_pod_KillTask_SandboxID_InitExecID_Success(t *testing.T) {
   175  	p, _ := setupTestPodWithFakes(t)
   176  	err := p.KillTask(context.TODO(), t.Name(), "", 0xf, false)
   177  	if err != nil {
   178  		t.Fatalf("should not have failed, got: %v", err)
   179  	}
   180  }
   181  
   182  func Test_pod_KillTask_SandboxID_InitExecID_All_Success(t *testing.T) {
   183  	p, _ := setupTestPodWithFakes(t)
   184  	// Add two workload tasks
   185  	setupTestTaskInPod(t, p)
   186  	setupTestTaskInPod(t, p)
   187  	err := p.KillTask(context.TODO(), t.Name(), "", 0xf, true)
   188  	if err != nil {
   189  		t.Fatalf("should not have failed, got: %v", err)
   190  	}
   191  }
   192  
   193  func Test_pod_KillTask_SandboxID_2ndExecID_Success(t *testing.T) {
   194  	p, t1 := setupTestPodWithFakes(t)
   195  	for k := range t1.execs {
   196  		err := p.KillTask(context.TODO(), t.Name(), k, 0xf, false)
   197  		if err != nil {
   198  			t.Fatalf("should not have failed, got: %v", err)
   199  		}
   200  	}
   201  }
   202  
   203  func Test_pod_KillTask_SandboxID_2ndExecID_All_Error(t *testing.T) {
   204  	p, t1 := setupTestPodWithFakes(t)
   205  	for k := range t1.execs {
   206  		err := p.KillTask(context.TODO(), t.Name(), k, 0xf, true)
   207  
   208  		verifyExpectedError(t, nil, err, errdefs.ErrFailedPrecondition)
   209  	}
   210  }
   211  
   212  func Test_pod_KillTask_WorkloadID_InitExecID_Success(t *testing.T) {
   213  	p, _ := setupTestPodWithFakes(t)
   214  	t1 := setupTestTaskInPod(t, p)
   215  
   216  	err := p.KillTask(context.TODO(), t1.ID(), "", 0xf, false)
   217  	if err != nil {
   218  		t.Fatalf("should not have failed, got: %v", err)
   219  	}
   220  }
   221  
   222  func Test_pod_KillTask_WorkloadID_InitExecID_All_Success(t *testing.T) {
   223  	p, _ := setupTestPodWithFakes(t)
   224  	t1 := setupTestTaskInPod(t, p)
   225  
   226  	err := p.KillTask(context.TODO(), t1.ID(), "", 0xf, true)
   227  	if err != nil {
   228  		t.Fatalf("should not have failed, got: %v", err)
   229  	}
   230  }
   231  
   232  func Test_pod_KillTask_WorkloadID_2ndExecID_Success(t *testing.T) {
   233  	p, _ := setupTestPodWithFakes(t)
   234  	t1 := setupTestTaskInPod(t, p)
   235  
   236  	for k := range t1.execs {
   237  		err := p.KillTask(context.TODO(), t1.ID(), k, 0xf, false)
   238  		if err != nil {
   239  			t.Fatalf("should not have failed, got: %v", err)
   240  		}
   241  	}
   242  }
   243  
   244  func Test_pod_KillTask_WorkloadID_2ndExecID_All_Error(t *testing.T) {
   245  	p, _ := setupTestPodWithFakes(t)
   246  	t1 := setupTestTaskInPod(t, p)
   247  
   248  	for k := range t1.execs {
   249  		err := p.KillTask(context.TODO(), t1.ID(), k, 0xf, true)
   250  
   251  		verifyExpectedError(t, nil, err, errdefs.ErrFailedPrecondition)
   252  	}
   253  }
   254  
   255  // delete tests
   256  
   257  func Test_pod_DeleteTask_SandboxID(t *testing.T) {
   258  	p, st := setupTestPodWithFakes(t)
   259  
   260  	err := p.KillTask(context.Background(), st.ID(), "", 0xf, true)
   261  	if err != nil {
   262  		t.Fatalf("should not have failed, got: %v", err)
   263  	}
   264  
   265  	err = p.DeleteTask(context.Background(), st.ID())
   266  	if err != nil {
   267  		t.Fatalf("should not have failed, got: %v", err)
   268  	}
   269  
   270  	// it should not be possible to delete the sandbox task
   271  	_, err = p.GetTask(t.Name())
   272  	if err != nil {
   273  		t.Fatalf("should not have failed, got: %v", err)
   274  	}
   275  }
   276  
   277  func Test_pod_DeleteTask_SandboxID_Running(t *testing.T) {
   278  	p, st := setupTestPodWithFakes(t)
   279  
   280  	// start the task
   281  	e, err := st.GetExec("")
   282  	if err != nil {
   283  		t.Fatalf("should not have failed, got: %v", err)
   284  	}
   285  	err = e.Start(context.Background())
   286  	if err != nil {
   287  		t.Fatalf("should not have failed, got: %v", err)
   288  	}
   289  
   290  	err = p.DeleteTask(context.Background(), st.ID())
   291  	verifyExpectedError(t, nil, err, errdefs.ErrFailedPrecondition)
   292  }
   293  
   294  func Test_pod_DeleteTask_SandboxID_Repeated(t *testing.T) {
   295  	p, st := setupTestPodWithFakes(t)
   296  
   297  	err := p.KillTask(context.Background(), st.ID(), "", 0xf, true)
   298  	if err != nil {
   299  		t.Fatalf("should not have failed, got: %v", err)
   300  	}
   301  
   302  	err = p.DeleteTask(context.Background(), st.ID())
   303  	if err != nil {
   304  		t.Fatalf("should not have failed, got: %v", err)
   305  	}
   306  
   307  	err = p.DeleteTask(context.Background(), st.ID())
   308  	if err != nil {
   309  		t.Fatalf("should not have failed, got: %v", err)
   310  	}
   311  }
   312  
   313  func Test_pod_DeleteTask_TaskID(t *testing.T) {
   314  	p, _ := setupTestPodWithFakes(t)
   315  	st := setupTestTaskInPod(t, p)
   316  
   317  	err := p.KillTask(context.Background(), st.ID(), "", 0xf, true)
   318  	if err != nil {
   319  		t.Fatalf("should not have failed, got: %v", err)
   320  	}
   321  
   322  	err = p.DeleteTask(context.Background(), st.ID())
   323  	if err != nil {
   324  		t.Fatalf("should not have failed, got: %v", err)
   325  	}
   326  
   327  	_, err = p.GetTask(st.ID())
   328  	verifyExpectedError(t, nil, err, errdefs.ErrNotFound)
   329  }
   330  
   331  func Test_pod_DeleteTask_TaskID_Running(t *testing.T) {
   332  	p, _ := setupTestPodWithFakes(t)
   333  	st := setupTestTaskInPod(t, p)
   334  
   335  	// start the task
   336  	e, err := st.GetExec("")
   337  	if err != nil {
   338  		t.Fatalf("should not have failed, got: %v", err)
   339  	}
   340  	err = e.Start(context.Background())
   341  	if err != nil {
   342  		t.Fatalf("should not have failed, got: %v", err)
   343  	}
   344  
   345  	err = p.DeleteTask(context.Background(), st.ID())
   346  	verifyExpectedError(t, nil, err, errdefs.ErrFailedPrecondition)
   347  
   348  	// should not actually delete the sandbox task
   349  	_, err = p.GetTask(t.Name())
   350  	if err != nil {
   351  		t.Fatalf("should not have failed, got: %v", err)
   352  	}
   353  
   354  	stp, err := p.GetTask(st.ID())
   355  	if err != nil {
   356  		t.Fatalf("should not have failed, got: %v", err)
   357  	}
   358  
   359  	if stp != st {
   360  		t.Fatalf("task should not have changed: %v != %v", st, stp)
   361  	}
   362  }
   363  
   364  func Test_pod_DeleteTask_TaskID_Repeated(t *testing.T) {
   365  	p, _ := setupTestPodWithFakes(t)
   366  	st := setupTestTaskInPod(t, p)
   367  
   368  	err := p.KillTask(context.Background(), st.ID(), "", 0xf, true)
   369  	if err != nil {
   370  		t.Fatalf("should not have failed, got: %v", err)
   371  	}
   372  
   373  	err = p.DeleteTask(context.Background(), st.ID())
   374  	if err != nil {
   375  		t.Fatalf("should not have failed, got: %v", err)
   376  	}
   377  
   378  	err = p.DeleteTask(context.Background(), st.ID())
   379  	verifyExpectedError(t, nil, err, errdefs.ErrNotFound)
   380  }
   381  
   382  func Test_pod_DeleteTask_TaskID_Not_Created(t *testing.T) {
   383  	p, _ := setupTestPodWithFakes(t)
   384  	// Add two workload tasks
   385  	setupTestTaskInPod(t, p)
   386  	setupTestTaskInPod(t, p)
   387  
   388  	err := p.KillTask(context.Background(), strconv.Itoa(rand.Int()), "", 0xf, true)
   389  	verifyExpectedError(t, nil, err, errdefs.ErrNotFound)
   390  }
   391  

View as plain text