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

Code before:
		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) {
		// Use constant seed for reproducibility
		randGen := rand.New(rand.NewSource(1982731263716))

		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 := randGen.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))
		}
	})
}

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

Review comment (bug):
Ah, for some reason I thought we use the random source to populate the generated containers properties with random values. 

I don't think randomizing the number of containers is a good idea.

A fixed-seed effectively reduces this to a fixed `num` value (which could even be 0 🙈), eliminating the usefulness of generating anything.
On the other hand, an actual random source makes the test behave differently on each invocation, making it potentially flaky or useless in general (you _definitely_ don't want your tests to pass/fail randomly).

I assume that the intent here is to test this against _different_ number of containers. In this case I think it's more appropriate to do exactly that - pick some values (like 5, 10, 50, 100, 500) for the number of containers, and run the test for each of these scenarios.

Code after:
			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))
			}
		})
	}
}

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

	_, err = d.Containers(context.Background(), &containertypes.ListOptions{
		Filters: filters.NewArgs(filters.Arg("invalid", "foo")),
	})
	assert.Assert(t, is.Error(err, "invalid filter 'invalid'"))
}

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

	var (