package hw3test import ( "math/rand" "reflect" "testing" ) func TestLargePutPlansKeepBoundaryWritesAndQueries(t *testing.T) { tests := []struct { name string runSeeds []int64 count int largeSeed int64 allHeaders bool compression bool }{ {"G6", []int64{7824, 1671, 3793, 272, 2715, 1436}, 25, 3793, false, false}, {"G7", []int64{3224, 7507, 4172, 7777, 6666, 6094, 6442}, 30, 3224, true, true}, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { context := NewTestContext(t) envGen := &EnvGen{ MaxDepth: 1, MaxDirs: 6, MaxFiles: 6, MaxFileSizeKB: 192 * 1024, FilenameGen: SimpleFilenameGenerator(16), } policy := &LargePutPolicy{ RunSeed: test.largeSeed, LargeSizes: []int64{160 << 20, 191 << 20}, OtherMaxBytes: 8 << 20, } options := RunOpts{ServerDomain: "localhost"} largePosts := 0 largeGets := 0 largeGzipGets := 0 for _, runSeed := range test.runSeeds { env, err := envGen.Generate(runSeed) if err != nil { t.Fatal(err) } r := rand.New(rand.NewSource(runSeed)) seeds := make([]int64, test.count) for i := range seeds { seeds[i] = r.Int63n(100000) } generator := &QueriesGen{ Count: test.count, GetFile: true, GetDirectory: true, Post: true, Put: true, Delete: true, Compression: test.compression, AllHeaders: test.allHeaders, LargePuts: policy, } queries := generator.Generate(context, env, envGen, seeds, options, runSeed) generator.LargePuts = nil baseline := generator.Generate(context, env, envGen, seeds, options, runSeed) if len(queries) != len(baseline) { t.Fatalf("run %d changed query count", runSeed) } state := env.Clone() var largePutSizes []int64 for i, query := range queries { if query.Method == "PUT" { baseline[i].FileContent.Size = query.FileContent.Size } if !reflect.DeepEqual(query, baseline[i]) { t.Fatalf("run %d changed query %d beyond PUT body size", runSeed, i) } action := query.Action(state, &options) if query.Path == "" && query.Method != "GET" { t.Fatal("generated a modifying request to the working directory") } if get, ok := action.(GetFileAction); ok && get.File.Size > 128<<20 { largeGets++ if get.Compression { largeGzipGets++ } } if query.Method == "PUT" { if query.FileContent.Size > 128<<20 { if _, ok := action.(ReplaceFileAction); !ok { t.Fatalf("run %d has a large PUT that cannot update a file", runSeed) } largePutSizes = append(largePutSizes, query.FileContent.Size) } else if query.FileContent.Size > policy.OtherMaxBytes { t.Fatalf("run %d has an unbounded PUT", runSeed) } } if query.Method == "POST" && query.FileContent != nil && query.FileContent.Size > 128<<20 { if _, ok := action.(CreateFileAction); ok { largePosts++ } } if action != nil { action.ApplyEnv(context, state) } } if runSeed == test.largeSeed { if !reflect.DeepEqual(largePutSizes, policy.LargeSizes) { t.Fatalf("run %d large PUT sizes: got %v, want %v", runSeed, largePutSizes, policy.LargeSizes) } } else if len(largePutSizes) != 0 { t.Fatalf("run %d has unexpected large PUTs", runSeed) } } if largePosts == 0 { t.Fatal("no successful POST larger than the solution memory limit") } if largeGets == 0 { t.Fatal("no successful GET larger than the solution memory limit") } if test.compression && largeGzipGets == 0 { t.Fatal("no gzip GET larger than the solution memory limit") } }) } }