Repository: moby/moby
File: daemon/list_test.go (Go)

Code before:
	return c
}

func containerListContainsName(containers []*containertypes.Summary, name string) bool {
	for _, ctr := range containers {
		for _, containerName := range ctr.Names {
			if containerName == name {
				return true
			}
		}
	}

	return false
}

func TestList(t *testing.T) {
	db, err := container.NewViewDB()
	assert.NilError(t, err)
	d := &Daemon{
		containersReplica: db,
	}

	// test list with no containers
	containerList, err := d.Containers(context.Background(), &containertypes.ListOptions{All: true})
	assert.NilError(t, err)
	assert.Assert(t, is.Len(containerList, 0))

	// test list of one container
	one := setupContainerWithName(t, "a1", d)
	containerList, err = d.Containers(context.Background(), &containertypes.ListOptions{All: true})
	assert.NilError(t, err)
	assert.Assert(t, is.Len(containerList, 1))
	assert.Assert(t, is.Equal(containerList[0].Names[0], one.Name))

	// test list with random number of containers
	db2, err := container.NewViewDB() // new DB to ignore prior containers
	assert.NilError(t, err)
	d = &Daemon{
		containersReplica: db2,
	}

	// start a random number of containers (between 0->64)
	num := rand.Intn(64)
	containers := make([]*container.Container, num)
	for i := range num {
		name := fmt.Sprintf("cont-%d", i)
		containers[i] = setupContainerWithName(t, name, d)
		// wait a bit to ensure container timestamps are separated enough so the
		// sort used by d.Containers() can deterministically sort them.
		time.Sleep(50 * time.Millisecond)
	}

Review comment (suggestion):
_Maybe_ over the top, and not a blocker for sure, but doing so may help encourage future additions to be easier to identify; we could use sub-tests here as well (I made a quick draft, but collapsed to reduce noise);

<details>

```go
func TestContainerList(t *testing.T) {
	db, err := container.NewViewDB()
	assert.NilError(t, err)
	d := &Daemon{
		containersReplica: db,
	}

	// test list with no containers
	t.Run("no containers", func(t *testing.T) {
		containerList, err := d.Containers(context.Background(), &containertypes.ListOptions{All: true})
		assert.NilError(t, err)
		assert.Assert(t, is.Len(containerList, 0))
	})

	// test list of one container
	t.Run("one container", func(t *testing.T) {
		one := setupContainerWithName(t, "a1", d)
		containerList, err := d.Containers(context.Background(), &containertypes.ListOptions{All: true})
		assert.NilError(t, err)
		assert.Assert(t, is.Len(containerList, 1))
		assert.Assert(t, is.Equal(containerList[0].Names[0], one.Name))
	})

	// test list with random number of containers
	t.Run("random", func(t *testing.T) {
		db2, err := container.NewViewDB() // new DB to ignore prior containers
		assert.NilError(t, err)
		d = &Daemon{
			containersReplica: db2,
		}

		// start a random number of containers (between 0->64)
		num := rand.Intn(64)
		containers := make([]*container.Container, num)
		for i := range num {
			name := fmt.Sprintf("cont-%d", i)
			containers[i] = setupContainerWithName(t, name, d)
			// wait a bit to ensure container timestamps are separated enough so the
			// sort used by d.Containers() can deterministically sort them.
			time.Sleep(50 * time.Millisecond)
		}

		// list them and verify correctness
		containerList, err := d.Containers(context.Background(), &containertypes.ListOptions{All: true})
		assert.NilError(t, err)
		assert.Assert(t, is.Len(containerList, num))

		for i := range num {
			// container list should be ordered in descending creation order
			assert.Assert(t, is.Equal(containerList[i].Names[0], containers[num-1-i].Name))
		}
	})
}
```

</details>

Code after:
}

func containerListContainsName(containers []*containertypes.Summary, name string) bool {
	for _, ctr := range containers {
		for _, containerName := range ctr.Names {
			if containerName == name {
				return true
			}
		}
	}

	return false
}

func TestContainerList(t *testing.T) {
	db, err := container.NewViewDB()
	assert.NilError(t, err)
	d := &Daemon{
		containersReplica: db,
	}

	// test list with different number of containers
	for _, num := range []int{0, 1, 2, 4, 8, 16, 32, 64, 100} {
		t.Run(fmt.Sprintf("%d containers", num), func(t *testing.T) {
			db, err := container.NewViewDB() // new DB to ignore prior containers
			assert.NilError(t, err)
			d = &Daemon{
				containersReplica: db,
			}

			// create the containers
			containers := make([]*container.Container, num)
			for i := range num {
				name := fmt.Sprintf("cont-%d", i)
				containers[i] = setupContainerWithName(t, name, d)
				// ensure container timestamps are separated enough so the
				// sort used by d.Containers() can deterministically sort them.
				if i > 0 {
					containers[i].Created = containers[i-1].Created.Add(time.Millisecond)
				}
			}

			// list them and verify correctness
			containerList, err := d.Containers(context.Background(), &containertypes.ListOptions{All: true})
			assert.NilError(t, err)
			assert.Assert(t, is.Len(containerList, num))

			for i := range num {
				// container list should be ordered in descending creation order
				assert.Assert(t, is.Equal(containerList[i].Names[0], containers[num-1-i].Name))
			}