@@ -319,7 +319,31 @@ func TestWorkspaceSerialization(t *testing.T) {
319
319
var _ = ps
320
320
321
321
org := dbgen .Organization (t , db , database.Organization {})
322
+
323
+ ctx := testutil .Context (t , testutil .WaitLong )
324
+ ctx = dbauthz .AsSystemRestricted (ctx )
325
+ group , err := db .InsertAllUsersGroup (ctx , org .ID )
326
+ require .NoError (t , err )
327
+
328
+ group , err = db .UpdateGroupByID (ctx , database.UpdateGroupByIDParams {
329
+ Name : group .Name ,
330
+ DisplayName : group .DisplayName ,
331
+ AvatarURL : group .AvatarURL ,
332
+ QuotaAllowance : 100 ,
333
+ ID : group .ID ,
334
+ })
335
+ require .NoError (t , err )
336
+
322
337
user := dbgen .User (t , db , database.User {})
338
+
339
+ dbgen .OrganizationMember (t , db , database.OrganizationMember {
340
+ UserID : user .ID ,
341
+ OrganizationID : org .ID ,
342
+ CreatedAt : dbtime .Now (),
343
+ UpdatedAt : dbtime .Now (),
344
+ Roles : []string {},
345
+ })
346
+
323
347
tpl := dbgen .Template (t , db , database.Template {
324
348
OrganizationID : org .ID ,
325
349
CreatedBy : user .ID ,
@@ -448,24 +472,130 @@ func TestWorkspaceSerialization(t *testing.T) {
448
472
449
473
var _ , _ = one , two
450
474
// Run order
475
+ one .GetQuota (ctx , t )
476
+ one .GetAllowance (ctx , t )
477
+
478
+ one .UpdateWorkspaceBuildCostByID (ctx , t , 10 )
479
+ two .UpdateWorkspaceBuildCostByID (ctx , t , 10 )
480
+
451
481
two .GetQuota (ctx , t )
452
482
two .GetAllowance (ctx , t )
453
483
484
+ // End commit
485
+ require .NoError (t , one .Done ())
486
+ require .NoError (t , two .Done ())
487
+ })
488
+
489
+ t .Run ("BumpLastUsedAt" , func (t * testing.T ) {
490
+ ctx := testutil .Context (t , testutil .WaitShort )
491
+ ctx = dbauthz .AsSystemRestricted (ctx )
492
+
493
+ two := dbtestutil .StartTx (t , db , & sql.TxOptions {
494
+ Isolation : sql .LevelSerializable ,
495
+ ReadOnly : false ,
496
+ })
497
+ one := newCommitter (t , db , workspace , workspaceResp .Build )
498
+
499
+ //two := newCommitter(t, db, workspaceTwo, workspaceResp.Build)
500
+
501
+ // Run order
454
502
one .GetQuota (ctx , t )
455
503
one .GetAllowance (ctx , t )
456
504
505
+ //two.UpdateWorkspaceBuildCostByID(ctx, t, 10)
506
+
507
+ //err := two.UpdateWorkspaceBuildCostByID(ctx, database.UpdateWorkspaceBuildCostByIDParams{
508
+ // ID: workspaceResp.Build.ID,
509
+ // DailyCost: 30,
510
+ //})
511
+ //require.NoError(t, err)
512
+
513
+ //q, err := two.GetQuotaConsumedForUser(ctx, database.GetQuotaConsumedForUserParams{
514
+ // OwnerID: user.ID,
515
+ // OrganizationID: workspace.OrganizationID,
516
+ //})
517
+ //require.NoError(t, err)
518
+ //fmt.Println(q)
519
+
457
520
one .UpdateWorkspaceBuildCostByID (ctx , t , 10 )
458
- two .UpdateWorkspaceBuildCostByID (ctx , t , 10 )
521
+
522
+ wg := sync.WaitGroup {}
523
+ wg .Add (1 )
524
+ go func () {
525
+ defer wg .Done ()
526
+ err = two .UpdateWorkspaceBuildDeadlineByID (ctx , database.UpdateWorkspaceBuildDeadlineByIDParams {
527
+ Deadline : dbtime .Now (),
528
+ MaxDeadline : dbtime .Now (),
529
+ UpdatedAt : dbtime .Now (),
530
+ ID : workspaceResp .Build .ID ,
531
+ })
532
+ require .NoError (t , err )
533
+ }()
534
+ time .Sleep (time .Millisecond * 800 )
535
+
536
+ //err = db.UpdateWorkspaceLastUsedAt(ctx, database.UpdateWorkspaceLastUsedAtParams{
537
+ // ID: workspace.ID,
538
+ // LastUsedAt: dbtime.Now(),
539
+ //})
540
+ //require.NoError(t, err)
541
+ //
542
+ //err = db.UpdateWorkspaceBuildCostByID(ctx, database.UpdateWorkspaceBuildCostByIDParams{
543
+ // ID: workspaceResp.Build.ID,
544
+ // DailyCost: 20,
545
+ //})
546
+ //require.NoError(t, err)
547
+
548
+ //two.GetQuota(ctx, t)
549
+ //two.GetAllowance(ctx, t)
459
550
460
551
// End commit
461
- err := one .Done ()
462
- err2 := two .Done ()
463
- require .NoError (t , err )
464
- require .NoError (t , err2 )
552
+ require .NoError (t , one .Done ())
553
+ wg .Wait ()
554
+ require .NoError (t , two .Done ())
465
555
})
466
556
467
557
// TODO: Try to fail a non-repeatable read only transaction
558
+ t .Run ("ReadStale" , func (t * testing.T ) {
559
+ ctx := testutil .Context (t , testutil .WaitLong )
560
+ ctx = dbauthz .AsSystemRestricted (ctx )
561
+
562
+ three := newCommitter (t , db , workspace , workspaceTwoResp .Build )
563
+ two := newCommitter (t , db , workspaceTwo , workspaceResp .Build )
564
+ one := newCommitter (t , db , workspace , workspaceResp .Build )
565
+ three .UpdateWorkspaceBuildCostByID (ctx , t , 10 )
566
+
567
+ // Run order
568
+
569
+ fmt .Println ("1" , one .GetQuota (ctx , t ))
570
+ one .GetAllowance (ctx , t )
571
+
572
+ one .UpdateWorkspaceBuildCostByID (ctx , t , 10 )
573
+
574
+ fmt .Println ("1a" , one .GetQuota (ctx , t ))
575
+
576
+ fmt .Println ("2a" , two .GetQuota (ctx , t ))
577
+ two .GetAllowance (ctx , t )
578
+
579
+ // End commit
580
+ require .NoError (t , one .Done ())
581
+
582
+ fmt .Println ("2a" , two .GetQuota (ctx , t ))
583
+ two .GetAllowance (ctx , t )
584
+
585
+ require .NoError (t , two .Done ())
586
+ require .NoError (t , three .Done ())
587
+
588
+ //allow, err = db.GetQuotaConsumedForUser(ctx, database.GetQuotaConsumedForUserParams{
589
+ // OwnerID: user.ID,
590
+ // OrganizationID: org.ID,
591
+ //})
592
+ //require.NoError(t, err)
593
+ //fmt.Println(allow)
594
+ })
595
+
468
596
// Autobuild, then quota, then autobuild read agin in the same tx
597
+ // https://www.richardstrnad.ch/posts/go-sql-how-to-get-detailed-error/
598
+ // https://blog.danslimmon.com/2024/01/10/why-transaction-order-matters-even-if-youre-only-reading/
469
599
}
470
600
471
601
func deprecatedQuotaEndpoint (ctx context.Context , client * codersdk.Client , userID string ) (codersdk.WorkspaceQuota , error ) {
0 commit comments