Repository: deno
Issue: Memory-backed KV data disappears mid test
Labels: needs info,ext/kv

Version: Deno x.x.x
Memory backed KV data disappearing under test

I'm trying to figure out why my tests are failing, and it turns out that data stored in KV is disappearing mid test. The tests are run with `DENO\_KV\_PATH=:memory: deno test -A ${file} --unstable-kv --inspect-brk`, so the KV store is in-memory.

The test calls a \`createUser()\` function to store a test user, followed by a \`createVote()\` function, which retrieves the stored user. I've verified that the user was stored correctly, but on attempting to retrieve it, there are no users in the store.

Relevant snippets of the code and output below. As you can see, the `createUser()` call stores the user which can then be retrieved by key and via `list()`; in the subsequent call to `createVote()` the user is no longer there; in fact there are no users at all, event though there were three stored moments ago.

So where is the data going? I did also verify that, in `createVote()`, the call to `kv.getMany()` *did* successfully retrieve the item, also created by the same test, so the KV store hasn't gotten completely wiped.

Any insights would be appreciated!

db\_test.ts:

    Deno.test("[db] getAreVotedByUser()", async () => {
      const item = randomItem();
      const user = randomUser();
      const vote = {
        itemId: item.id,
        userLogin: user.login,
        createdAt: new Date(),
      };
    
      ...
    
      await createItem(item);
      await createUser(user);
      await createVote(vote);
    
      ...
    });

db-users.ts:

    export async function createUser(user: User) {
      const usersKey = ["users", user.login];
      const usersBySessionKey = ["users_by_session", user.sessionId];

      const atomicOp = kv.atomic()
        .check({ key: usersKey, versionstamp: null })
        .check({ key: usersBySessionKey, versionstamp: null })
        .set(usersKey, user)
        .set(usersBySessionKey, user);

      const res = await atomicOp.commit();
      if (!res.ok) throw new Error("Failed to create user");

      const created = await kv.get(usersKey);
      console.log("New user:", user);
      console.log("Created user:", created);
      console.log("All known users:");
      const allusers = kv.list({ prefix: ["users"] });
      for await (const entry of allusers) {
        console.log(entry.value);
      }
      console.log("done");
    }

db-items.ts:

    export async function createVote(vote: Vote) {
      const itemKey = ["items", vote.itemId];
      const userKey = ["users", vote.userLogin];
      const [itemRes, userRes] = await kv.getMany<[Item, User]>([itemKey, userKey]);

      console.log("=====");
      console.log((await kv.get(userKey)).value);
      console.log("=====");
      console.log("All known users:");
      const allusers = kv.list({ prefix: ["users"] });
      for await (const entry of allusers) {
        console.log(entry.value);
      }
      console.log("=====");

      const item = itemRes.value;
      const user = userRes.value;
      if (item === null) throw new Deno.errors.NotFound("Item not found");
      if (user === null) throw new Deno.errors.NotFound("User not found");

      ...
    }

Output:

    New user: {
      login: "3d37054b-8e08-46c3-beb0-14793e682355",
      sessionId: "0d399be6-2486-4208-b00f-f98030b946a5",
      isSubscribed: false,
      stripeCustomerId: "644fd255-e1f5-46d8-a7b1-2e1e75f78202"
    }
    Created user: {
      key: [ "users", "3d37054b-8e08-46c3-beb0-14793e682355" ],
      value: {
        login: "3d37054b-8e08-46c3-beb0-14793e682355",
        sessionId: "0d399be6-2486-4208-b00f-f98030b946a5",
        isSubscribed: false,
        stripeCustomerId: "644fd255-e1f5-46d8-a7b1-2e1e75f78202"
      },
      versionstamp: "00000000000000040000"
    }
    All known users: