...

Source file src/github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/service_internal_taskshim_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  	"os"
    10  	"path/filepath"
    11  	"strconv"
    12  	"testing"
    13  	"time"
    14  
    15  	"github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/options"
    16  	"github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/stats"
    17  	"github.com/Microsoft/hcsshim/internal/hcsoci"
    18  	"github.com/Microsoft/hcsshim/pkg/ctrdtaskapi"
    19  	"github.com/containerd/containerd/errdefs"
    20  	"github.com/containerd/containerd/runtime/v2/task"
    21  	"github.com/containerd/typeurl"
    22  	"github.com/opencontainers/runtime-spec/specs-go"
    23  )
    24  
    25  func setupTaskServiceWithFakes(t *testing.T) (*service, *testShimTask, *testShimExec) {
    26  	t.Helper()
    27  	tid := strconv.Itoa(rand.Int())
    28  
    29  	s, err := NewService(WithTID(tid), WithIsSandbox(false))
    30  	if err != nil {
    31  		t.Fatalf("could not create service: %v", err)
    32  	}
    33  
    34  	// clean up the service
    35  	t.Cleanup(func() {
    36  		if _, err := s.shutdownInternal(context.Background(), &task.ShutdownRequest{
    37  			ID:  s.tid,
    38  			Now: true,
    39  		}); err != nil {
    40  			t.Fatalf("could not shutdown service: %v", err)
    41  		}
    42  	})
    43  
    44  	task := &testShimTask{
    45  		id:    tid,
    46  		exec:  newTestShimExec(tid, tid, 10),
    47  		execs: make(map[string]*testShimExec),
    48  	}
    49  	secondExecID := strconv.Itoa(rand.Int())
    50  	secondExec := newTestShimExec(tid, secondExecID, 101)
    51  	task.execs[secondExecID] = secondExec
    52  	s.taskOrPod.Store(task)
    53  	return s, task, secondExec
    54  }
    55  
    56  func Test_TaskShim_getTask_NotCreated_Error(t *testing.T) {
    57  	s := service{
    58  		tid:       t.Name(),
    59  		isSandbox: false,
    60  	}
    61  
    62  	st, err := s.getTask(t.Name())
    63  
    64  	verifyExpectedError(t, st, err, errdefs.ErrNotFound)
    65  }
    66  
    67  func Test_TaskShim_getTask_Created_DifferentID_Error(t *testing.T) {
    68  	s, _, _ := setupTaskServiceWithFakes(t)
    69  
    70  	st, err := s.getTask("thisidwontmatch")
    71  
    72  	verifyExpectedError(t, st, err, errdefs.ErrNotFound)
    73  }
    74  
    75  func Test_TaskShim_getTask_Created_CorrectID_Success(t *testing.T) {
    76  	s, t1, _ := setupTaskServiceWithFakes(t)
    77  
    78  	st, err := s.getTask(t1.ID())
    79  	if err != nil {
    80  		t.Fatalf("should have not failed with error, got: %v", err)
    81  	}
    82  	if st != t1 {
    83  		t.Fatal("should have returned a valid task")
    84  	}
    85  }
    86  
    87  func Test_TaskShim_stateInternal_NoTask_Error(t *testing.T) {
    88  	s := service{
    89  		tid:       t.Name(),
    90  		isSandbox: false,
    91  	}
    92  
    93  	resp, err := s.stateInternal(context.TODO(), &task.StateRequest{ID: t.Name()})
    94  
    95  	verifyExpectedError(t, resp, err, errdefs.ErrNotFound)
    96  }
    97  
    98  func Test_TaskShim_stateInternal_InitTaskID_DifferentExecID_Error(t *testing.T) {
    99  	s, t1, _ := setupTaskServiceWithFakes(t)
   100  
   101  	resp, err := s.stateInternal(context.TODO(), &task.StateRequest{
   102  		ID:     t1.ID(),
   103  		ExecID: "thisshouldnotmatch",
   104  	})
   105  
   106  	verifyExpectedError(t, resp, err, errdefs.ErrNotFound)
   107  }
   108  
   109  func Test_TaskShim_stateInternal_InitTaskID_InitExecID_Success(t *testing.T) {
   110  	s, t1, _ := setupTaskServiceWithFakes(t)
   111  
   112  	resp, err := s.stateInternal(context.TODO(), &task.StateRequest{
   113  		ID:     t1.ID(),
   114  		ExecID: "",
   115  	})
   116  	if err != nil {
   117  		t.Fatalf("should not have failed with error got: %v", err)
   118  	}
   119  	if resp == nil {
   120  		t.Fatal("should have returned StateResponse")
   121  	}
   122  	if resp.ID != t1.ID() {
   123  		t.Fatalf("StateResponse.ID expected '%s' got '%s'", t1.ID(), resp.ID)
   124  	}
   125  	if resp.ExecID != t1.ID() {
   126  		t.Fatalf("StateResponse.ExecID expected '%s' got '%s'", t1.ID(), resp.ExecID)
   127  	}
   128  	if resp.Pid != uint32(t1.exec.pid) {
   129  		t.Fatalf("should have returned init pid, got: %v", resp.Pid)
   130  	}
   131  }
   132  
   133  func Test_TaskShim_stateInternal_InitTaskID_2ndExecID_Success(t *testing.T) {
   134  	s, t1, e2 := setupTaskServiceWithFakes(t)
   135  
   136  	resp, err := s.stateInternal(context.TODO(), &task.StateRequest{
   137  		ID:     t1.ID(),
   138  		ExecID: e2.ID(),
   139  	})
   140  	if err != nil {
   141  		t.Fatalf("should not have failed with error got: %v", err)
   142  	}
   143  	if resp == nil {
   144  		t.Fatal("should have returned StateResponse")
   145  	}
   146  	if resp.ID != t1.ID() {
   147  		t.Fatalf("StateResponse.ID expected '%s' got '%s'", t1.ID(), resp.ID)
   148  	}
   149  	if resp.ExecID != e2.ID() {
   150  		t.Fatalf("StateResponse.ExecID expected '%s' got '%s'", e2.ID(), resp.ExecID)
   151  	}
   152  	if resp.Pid != uint32(t1.execs[e2.ID()].pid) {
   153  		t.Fatalf("should have returned 2nd exec pid, got: %v", resp.Pid)
   154  	}
   155  }
   156  
   157  // TODO: Test_TaskShim_createInternal_*
   158  
   159  func Test_TaskShim_startInternal_NoTask_Error(t *testing.T) {
   160  	s := service{
   161  		tid:       t.Name(),
   162  		isSandbox: true,
   163  	}
   164  
   165  	resp, err := s.startInternal(context.TODO(), &task.StartRequest{ID: t.Name()})
   166  
   167  	verifyExpectedError(t, resp, err, errdefs.ErrNotFound)
   168  }
   169  
   170  func Test_TaskShim_startInternal_ValidTask_DifferentExecID_Error(t *testing.T) {
   171  	s, t1, _ := setupTaskServiceWithFakes(t)
   172  
   173  	resp, err := s.startInternal(context.TODO(), &task.StartRequest{
   174  		ID:     t1.ID(),
   175  		ExecID: "thisshouldnotmatch",
   176  	})
   177  
   178  	verifyExpectedError(t, resp, err, errdefs.ErrNotFound)
   179  }
   180  
   181  func Test_TaskShim_startInternal_InitTaskID_InitExecID_Success(t *testing.T) {
   182  	s, t1, _ := setupTaskServiceWithFakes(t)
   183  
   184  	resp, err := s.startInternal(context.TODO(), &task.StartRequest{
   185  		ID:     t1.ID(),
   186  		ExecID: "",
   187  	})
   188  	if err != nil {
   189  		t.Fatalf("should not have failed with error got: %v", err)
   190  	}
   191  	if resp == nil {
   192  		t.Fatal("should have returned StartResponse")
   193  	}
   194  	if resp.Pid != uint32(t1.exec.pid) {
   195  		t.Fatal("should have returned init pid")
   196  	}
   197  }
   198  
   199  func Test_TaskShim_startInternal_InitTaskID_2ndExecID_Success(t *testing.T) {
   200  	s, t1, e2 := setupTaskServiceWithFakes(t)
   201  
   202  	resp, err := s.startInternal(context.TODO(), &task.StartRequest{
   203  		ID:     t1.ID(),
   204  		ExecID: e2.ID(),
   205  	})
   206  	if err != nil {
   207  		t.Fatalf("should not have failed with error got: %v", err)
   208  	}
   209  	if resp == nil {
   210  		t.Fatal("should have returned StartResponse")
   211  	}
   212  	if resp.Pid != uint32(t1.execs[e2.ID()].pid) {
   213  		t.Fatal("should have returned 2nd pid")
   214  	}
   215  }
   216  
   217  func Test_TaskShim_deleteInternal_NoTask_Error(t *testing.T) {
   218  	s := service{
   219  		tid:       t.Name(),
   220  		isSandbox: true,
   221  	}
   222  
   223  	resp, err := s.deleteInternal(context.TODO(), &task.DeleteRequest{ID: t.Name()})
   224  
   225  	verifyExpectedError(t, resp, err, errdefs.ErrNotFound)
   226  }
   227  
   228  func Test_TaskShim_deleteInternal_ValidTask_DifferentExecID_Error(t *testing.T) {
   229  	s, t1, _ := setupTaskServiceWithFakes(t)
   230  
   231  	resp, err := s.deleteInternal(context.TODO(), &task.DeleteRequest{
   232  		ID:     t1.ID(),
   233  		ExecID: "thisshouldnotmatch",
   234  	})
   235  
   236  	verifyExpectedError(t, resp, err, errdefs.ErrNotFound)
   237  }
   238  
   239  func Test_TaskShim_deleteInternal_InitTaskID_InitExecID_Success(t *testing.T) {
   240  	s, t1, _ := setupTaskServiceWithFakes(t)
   241  
   242  	resp, err := s.deleteInternal(context.TODO(), &task.DeleteRequest{
   243  		ID:     t1.ID(),
   244  		ExecID: "",
   245  	})
   246  	if err != nil {
   247  		t.Fatalf("should not have failed with error got: %v", err)
   248  	}
   249  	if resp == nil {
   250  		t.Fatal("should have returned DeleteResponse")
   251  	}
   252  	if resp.Pid != uint32(t1.exec.pid) {
   253  		t.Fatal("should have returned init pid")
   254  	}
   255  }
   256  
   257  func Test_TaskShim_deleteInternal_InitTaskID_2ndExecID_Success(t *testing.T) {
   258  	s, t1, e2 := setupTaskServiceWithFakes(t)
   259  
   260  	// capture the t2 task as it will be deleted
   261  	t2t := t1.execs[e2.ID()]
   262  
   263  	resp, err := s.deleteInternal(context.TODO(), &task.DeleteRequest{
   264  		ID:     t1.ID(),
   265  		ExecID: e2.ID(),
   266  	})
   267  	if err != nil {
   268  		t.Fatalf("should not have failed with error got: %v", err)
   269  	}
   270  	if resp == nil {
   271  		t.Fatal("should have returned DeleteResponse")
   272  	}
   273  	if resp.Pid != uint32(t2t.pid) {
   274  		t.Fatal("should have returned 2nd pid")
   275  	}
   276  	if _, ok := t1.execs[e2.ID()]; ok {
   277  		t.Fatal("should have deleted the 2nd exec")
   278  	}
   279  }
   280  
   281  func Test_TaskShim_pidsInternal_NoTask_Error(t *testing.T) {
   282  	s := service{
   283  		tid:       t.Name(),
   284  		isSandbox: true,
   285  	}
   286  
   287  	resp, err := s.pidsInternal(context.TODO(), &task.PidsRequest{ID: t.Name()})
   288  
   289  	verifyExpectedError(t, resp, err, errdefs.ErrNotFound)
   290  }
   291  
   292  func Test_TaskShim_pidsInternal_InitTaskID_Success(t *testing.T) {
   293  	s, t1, e2 := setupTaskServiceWithFakes(t)
   294  
   295  	resp, err := s.pidsInternal(context.TODO(), &task.PidsRequest{ID: t1.ID()})
   296  	if err != nil {
   297  		t.Fatalf("should not have failed with error got: %v", err)
   298  	}
   299  	if resp == nil {
   300  		t.Fatal("should have returned PidsResponse")
   301  	}
   302  	if len(resp.Processes) != 2 {
   303  		t.Fatalf("should have returned len(processes) == 1, got: %v", len(resp.Processes))
   304  	}
   305  	if resp.Processes[0].Pid != uint32(t1.exec.pid) {
   306  		t.Fatal("should have returned init pid")
   307  	}
   308  	if resp.Processes[0].Info == nil {
   309  		t.Fatal("should have returned init pid info")
   310  	}
   311  	if resp.Processes[1].Pid != uint32(t1.execs[e2.ID()].pid) {
   312  		t.Fatal("should have returned 2nd pid")
   313  	}
   314  	if resp.Processes[1].Info == nil {
   315  		t.Fatal("should have returned 2nd pid info")
   316  	}
   317  	u, err := typeurl.UnmarshalAny(resp.Processes[1].Info)
   318  	if err != nil {
   319  		t.Fatalf("failed to unmarshal 2nd pid info, err: %v", err)
   320  	}
   321  	pi := u.(*options.ProcessDetails)
   322  	if pi.ExecID != e2.ID() {
   323  		t.Fatalf("should have returned 2nd pid ExecID, got: %v", pi.ExecID)
   324  	}
   325  }
   326  
   327  func Test_TaskShim_pauseInternal_Error(t *testing.T) {
   328  	s := service{
   329  		tid:       t.Name(),
   330  		isSandbox: true,
   331  	}
   332  
   333  	resp, err := s.pauseInternal(context.TODO(), &task.PauseRequest{ID: t.Name()})
   334  
   335  	verifyExpectedError(t, resp, err, errdefs.ErrNotImplemented)
   336  }
   337  
   338  func Test_TaskShim_resumeInternal_Error(t *testing.T) {
   339  	s := service{
   340  		tid:       t.Name(),
   341  		isSandbox: true,
   342  	}
   343  
   344  	resp, err := s.resumeInternal(context.TODO(), &task.ResumeRequest{ID: t.Name()})
   345  
   346  	verifyExpectedError(t, resp, err, errdefs.ErrNotImplemented)
   347  }
   348  
   349  func Test_TaskShim_checkpointInternal_Error(t *testing.T) {
   350  	s := service{
   351  		tid:       t.Name(),
   352  		isSandbox: true,
   353  	}
   354  
   355  	resp, err := s.checkpointInternal(context.TODO(), &task.CheckpointTaskRequest{ID: t.Name()})
   356  
   357  	verifyExpectedError(t, resp, err, errdefs.ErrNotImplemented)
   358  }
   359  
   360  func Test_TaskShim_killInternal_NoTask_Error(t *testing.T) {
   361  	s := service{
   362  		tid:       t.Name(),
   363  		isSandbox: true,
   364  	}
   365  
   366  	resp, err := s.killInternal(context.TODO(), &task.KillRequest{ID: t.Name()})
   367  
   368  	verifyExpectedError(t, resp, err, errdefs.ErrNotFound)
   369  }
   370  
   371  func Test_TaskShim_killInternal_InitTaskID_DifferentExecID_Error(t *testing.T) {
   372  	s, t1, _ := setupTaskServiceWithFakes(t)
   373  
   374  	resp, err := s.killInternal(context.TODO(), &task.KillRequest{
   375  		ID:     t1.ID(),
   376  		ExecID: "thisshouldnotmatch",
   377  	})
   378  
   379  	verifyExpectedError(t, resp, err, errdefs.ErrNotFound)
   380  }
   381  
   382  func Test_TaskShim_killInternal_InitTaskID_InitExecID_Success(t *testing.T) {
   383  	s, t1, _ := setupTaskServiceWithFakes(t)
   384  
   385  	resp, err := s.killInternal(context.TODO(), &task.KillRequest{
   386  		ID:     t1.ID(),
   387  		ExecID: "",
   388  	})
   389  	if err != nil {
   390  		t.Fatalf("should not have failed with error got: %v", err)
   391  	}
   392  	if resp == nil {
   393  		t.Fatal("should have returned KillResponse")
   394  	}
   395  }
   396  
   397  func Test_TaskShim_killInternal_InitTaskID_2ndExecID_Success(t *testing.T) {
   398  	s, t1, e2 := setupTaskServiceWithFakes(t)
   399  
   400  	resp, err := s.killInternal(context.TODO(), &task.KillRequest{
   401  		ID:     t1.ID(),
   402  		ExecID: e2.ID(),
   403  	})
   404  	if err != nil {
   405  		t.Fatalf("should not have failed with error got: %v", err)
   406  	}
   407  	if resp == nil {
   408  		t.Fatal("should have returned KillResponse")
   409  	}
   410  }
   411  
   412  // TODO: Test_TaskShim_execInternal_*
   413  
   414  func Test_TaskShim_resizePtyInternal_NoTask_Error(t *testing.T) {
   415  	s := service{
   416  		tid:       t.Name(),
   417  		isSandbox: true,
   418  	}
   419  
   420  	resp, err := s.resizePtyInternal(context.TODO(), &task.ResizePtyRequest{ID: t.Name()})
   421  
   422  	verifyExpectedError(t, resp, err, errdefs.ErrNotFound)
   423  }
   424  
   425  func Test_TaskShim_resizePtyInternal_InitTaskID_DifferentExecID_Error(t *testing.T) {
   426  	s, t1, _ := setupTaskServiceWithFakes(t)
   427  
   428  	resp, err := s.resizePtyInternal(context.TODO(), &task.ResizePtyRequest{
   429  		ID:     t1.ID(),
   430  		ExecID: "thisshouldnotmatch",
   431  	})
   432  
   433  	verifyExpectedError(t, resp, err, errdefs.ErrNotFound)
   434  }
   435  
   436  func Test_TaskShim_resizePtyInternal_InitTaskID_InitExecID_Success(t *testing.T) {
   437  	s, t1, _ := setupTaskServiceWithFakes(t)
   438  
   439  	resp, err := s.resizePtyInternal(context.TODO(), &task.ResizePtyRequest{
   440  		ID:     t1.ID(),
   441  		ExecID: "",
   442  	})
   443  	if err != nil {
   444  		t.Fatalf("should not have failed with error got: %v", err)
   445  	}
   446  	if resp == nil {
   447  		t.Fatal("should have returned ResizePtyResponse")
   448  	}
   449  }
   450  
   451  func Test_TaskShim_resizePtyInternal_InitTaskID_2ndExecID_Success(t *testing.T) {
   452  	s, t1, e2 := setupTaskServiceWithFakes(t)
   453  
   454  	resp, err := s.resizePtyInternal(context.TODO(), &task.ResizePtyRequest{
   455  		ID:     t1.ID(),
   456  		ExecID: e2.ID(),
   457  	})
   458  	if err != nil {
   459  		t.Fatalf("should not have failed with error got: %v", err)
   460  	}
   461  	if resp == nil {
   462  		t.Fatal("should have returned ResizePtyResponse")
   463  	}
   464  }
   465  
   466  func Test_TaskShim_closeIOInternal_NoTask_Error(t *testing.T) {
   467  	s := service{
   468  		tid:       t.Name(),
   469  		isSandbox: true,
   470  	}
   471  
   472  	resp, err := s.closeIOInternal(context.TODO(), &task.CloseIORequest{ID: t.Name()})
   473  
   474  	verifyExpectedError(t, resp, err, errdefs.ErrNotFound)
   475  }
   476  
   477  func Test_TaskShim_closeIOInternal_InitTaskID_DifferentExecID_Error(t *testing.T) {
   478  	s, t1, _ := setupTaskServiceWithFakes(t)
   479  
   480  	resp, err := s.closeIOInternal(context.TODO(), &task.CloseIORequest{
   481  		ID:     t1.ID(),
   482  		ExecID: "thisshouldnotmatch",
   483  	})
   484  
   485  	verifyExpectedError(t, resp, err, errdefs.ErrNotFound)
   486  }
   487  
   488  func Test_TaskShim_closeIOInternal_InitTaskID_InitExecID_Success(t *testing.T) {
   489  	s, t1, _ := setupTaskServiceWithFakes(t)
   490  
   491  	resp, err := s.closeIOInternal(context.TODO(), &task.CloseIORequest{
   492  		ID:     t1.ID(),
   493  		ExecID: "",
   494  	})
   495  	if err != nil {
   496  		t.Fatalf("should not have failed with error got: %v", err)
   497  	}
   498  	if resp == nil {
   499  		t.Fatal("should have returned CloseIOResponse")
   500  	}
   501  }
   502  
   503  func Test_TaskShim_closeIOInternal_InitTaskID_2ndExecID_Success(t *testing.T) {
   504  	s, t1, e2 := setupTaskServiceWithFakes(t)
   505  
   506  	resp, err := s.closeIOInternal(context.TODO(), &task.CloseIORequest{
   507  		ID:     t1.ID(),
   508  		ExecID: e2.ID(),
   509  	})
   510  	if err != nil {
   511  		t.Fatalf("should not have failed with error got: %v", err)
   512  	}
   513  	if resp == nil {
   514  		t.Fatal("should have returned CloseIOResponse")
   515  	}
   516  }
   517  
   518  func Test_TaskShim_updateInternal_Success(t *testing.T) {
   519  	s, t1, _ := setupTaskServiceWithFakes(t)
   520  
   521  	var limit uint64 = 100
   522  	resources := &specs.WindowsResources{
   523  		Memory: &specs.WindowsMemoryResources{
   524  			Limit: &limit,
   525  		},
   526  	}
   527  
   528  	any, err := typeurl.MarshalAny(resources)
   529  	if err != nil {
   530  		t.Fatal(err)
   531  	}
   532  
   533  	resp, err := s.updateInternal(context.TODO(), &task.UpdateTaskRequest{ID: t1.ID(), Resources: any})
   534  	if err != nil {
   535  		t.Fatalf("should not have failed with error, got: %v", err)
   536  	}
   537  	if resp == nil {
   538  		t.Fatalf("should have returned an empty resp")
   539  	}
   540  }
   541  
   542  // Tests if a requested mount is valid for windows containers.
   543  // Currently only host volumes/directories are supported to be mounted
   544  // on a running windows container.
   545  func Test_TaskShimWindowsMount_updateInternal_Success(t *testing.T) {
   546  	s, t1, _ := setupTaskServiceWithFakes(t)
   547  	t1.isWCOW = true
   548  
   549  	hostRWSharedDirectory := t.TempDir()
   550  	fRW, _ := os.OpenFile(filepath.Join(hostRWSharedDirectory, "readwrite"), os.O_RDWR|os.O_CREATE, 0755)
   551  	fRW.Close()
   552  
   553  	resources := &ctrdtaskapi.ContainerMount{
   554  		HostPath:      hostRWSharedDirectory,
   555  		ContainerPath: hostRWSharedDirectory,
   556  		ReadOnly:      true,
   557  		Type:          "",
   558  	}
   559  	any, err := typeurl.MarshalAny(resources)
   560  	if err != nil {
   561  		t.Fatal(err)
   562  	}
   563  
   564  	resp, err := s.updateInternal(context.TODO(), &task.UpdateTaskRequest{ID: t1.ID(), Resources: any})
   565  	if err != nil {
   566  		t.Fatalf("should not have failed update mount with error, got: %v", err)
   567  	}
   568  	if resp == nil {
   569  		t.Fatalf("should have returned an empty resp")
   570  	}
   571  }
   572  
   573  func Test_TaskShimWindowsMount_updateInternal_Error(t *testing.T) {
   574  	s, t1, _ := setupTaskServiceWithFakes(t)
   575  	t1.isWCOW = true
   576  
   577  	hostRWSharedDirectory := t.TempDir()
   578  	tmpVhdPath := filepath.Join(hostRWSharedDirectory, "test-vhd.vhdx")
   579  
   580  	fRW, _ := os.OpenFile(filepath.Join(tmpVhdPath, "readwrite"), os.O_RDWR|os.O_CREATE, 0755)
   581  	fRW.Close()
   582  
   583  	resources := &ctrdtaskapi.ContainerMount{
   584  		HostPath:      tmpVhdPath,
   585  		ContainerPath: tmpVhdPath,
   586  		ReadOnly:      true,
   587  		Type:          hcsoci.MountTypeVirtualDisk,
   588  	}
   589  	any, err := typeurl.MarshalAny(resources)
   590  	if err != nil {
   591  		t.Fatal(err)
   592  	}
   593  
   594  	resp, err := s.updateInternal(context.TODO(), &task.UpdateTaskRequest{ID: t1.ID(), Resources: any})
   595  	if err == nil {
   596  		t.Fatalf("should have failed update mount with error")
   597  	}
   598  	if resp != nil {
   599  		t.Fatalf("should have returned a nil resp, got: %v", resp)
   600  	}
   601  }
   602  
   603  func Test_TaskShim_updateInternal_Error(t *testing.T) {
   604  	s, t1, _ := setupTaskServiceWithFakes(t)
   605  
   606  	// resources must be of type *WindowsResources or *LinuxResources
   607  	resources := &specs.Process{}
   608  	any, err := typeurl.MarshalAny(resources)
   609  	if err != nil {
   610  		t.Fatal(err)
   611  	}
   612  
   613  	_, err = s.updateInternal(context.TODO(), &task.UpdateTaskRequest{ID: t1.ID(), Resources: any})
   614  	if err == nil {
   615  		t.Fatal("expected to get an error for incorrect resource's type")
   616  	}
   617  	if err != errNotSupportedResourcesRequest {
   618  		t.Fatalf("expected to get errNotSupportedResourcesRequest, instead got %v", err)
   619  	}
   620  }
   621  
   622  func Test_TaskShim_waitInternal_NoTask_Error(t *testing.T) {
   623  	s := service{
   624  		tid:       t.Name(),
   625  		isSandbox: true,
   626  	}
   627  
   628  	resp, err := s.waitInternal(context.TODO(), &task.WaitRequest{ID: t.Name()})
   629  
   630  	verifyExpectedError(t, resp, err, errdefs.ErrNotFound)
   631  }
   632  
   633  func Test_TaskShim_waitInternal_InitTaskID_DifferentExecID_Error(t *testing.T) {
   634  	s, t1, _ := setupTaskServiceWithFakes(t)
   635  
   636  	resp, err := s.waitInternal(context.TODO(), &task.WaitRequest{
   637  		ID:     t1.ID(),
   638  		ExecID: "thisshouldnotmatch",
   639  	})
   640  
   641  	verifyExpectedError(t, resp, err, errdefs.ErrNotFound)
   642  }
   643  
   644  func Test_TaskShim_waitInternal_InitTaskID_InitExecID_Success(t *testing.T) {
   645  	s, t1, _ := setupTaskServiceWithFakes(t)
   646  
   647  	resp, err := s.waitInternal(context.TODO(), &task.WaitRequest{
   648  		ID:     t1.ID(),
   649  		ExecID: "",
   650  	})
   651  	if err != nil {
   652  		t.Fatalf("should not have failed with error got: %v", err)
   653  	}
   654  	if resp == nil {
   655  		t.Fatal("should have returned WaitResponse")
   656  	}
   657  	if resp.ExitStatus != t1.exec.Status().ExitStatus {
   658  		t.Fatal("should have returned exit status for init")
   659  	}
   660  }
   661  
   662  func Test_TaskShim_waitInternal_InitTaskID_2ndExecID_Success(t *testing.T) {
   663  	s, t1, e2 := setupTaskServiceWithFakes(t)
   664  
   665  	resp, err := s.waitInternal(context.TODO(), &task.WaitRequest{
   666  		ID:     t1.ID(),
   667  		ExecID: e2.ID(),
   668  	})
   669  	if err != nil {
   670  		t.Fatalf("should not have failed with error got: %v", err)
   671  	}
   672  	if resp == nil {
   673  		t.Fatal("should have returned WaitResponse")
   674  	}
   675  	if resp.ExitStatus != t1.execs[e2.ID()].Status().ExitStatus {
   676  		t.Fatal("should have returned exit status for init")
   677  	}
   678  }
   679  
   680  func Test_TaskShim_statsInternal_InitTaskID_Success(t *testing.T) {
   681  	testNames := []string{"WCOW", "LCOW"}
   682  	for i, isWCOW := range []bool{true, false} {
   683  		t.Run(testNames[i], func(t *testing.T) {
   684  			s, t1, _ := setupTaskServiceWithFakes(t)
   685  			t1.isWCOW = isWCOW
   686  
   687  			resp, err := s.statsInternal(context.TODO(), &task.StatsRequest{ID: t1.ID()})
   688  
   689  			if err != nil {
   690  				t.Fatalf("should not have failed with error got: %v", err)
   691  			}
   692  			if resp == nil || resp.Stats == nil {
   693  				t.Fatal("should have returned valid stats response")
   694  			}
   695  			statsI, err := typeurl.UnmarshalAny(resp.Stats)
   696  			if err != nil {
   697  				t.Fatalf("should not have failed to unmarshal StatsResponse got: %v", err)
   698  			}
   699  			stats := statsI.(*stats.Statistics)
   700  			verifyExpectedStats(t, t1.isWCOW, true, stats)
   701  		})
   702  	}
   703  }
   704  
   705  func Test_TaskShim_shutdownInternal(t *testing.T) {
   706  	for _, now := range []bool{true, false} {
   707  		t.Run(fmt.Sprintf("%s_Now_%t", t.Name(), now), func(t *testing.T) {
   708  			s, _, _ := setupTaskServiceWithFakes(t)
   709  
   710  			if s.IsShutdown() {
   711  				t.Fatal("service prematurely shutdown")
   712  			}
   713  
   714  			_, err := s.shutdownInternal(context.Background(), &task.ShutdownRequest{
   715  				ID:  s.tid,
   716  				Now: now,
   717  			})
   718  			if err != nil {
   719  				t.Fatalf("could not shut down service: %v", err)
   720  			}
   721  
   722  			tm := time.NewTimer(5 * time.Millisecond)
   723  			select {
   724  			case <-tm.C:
   725  				t.Fatalf("shutdown channel did not close")
   726  			case <-s.Done():
   727  				tm.Stop()
   728  			}
   729  
   730  			if !s.IsShutdown() {
   731  				t.Fatal("service did not shutdown")
   732  			}
   733  		})
   734  	}
   735  }
   736  

View as plain text