On 09/06/22 11:19, Eric Blake wrote:
> On Mon, Sep 05, 2022 at 02:10:36PM +0200, Laszlo Ersek wrote:
>> On 09/03/22 00:14, Eric Blake wrote:
>>> This proves that the stat counters increment as desired, as well as
>>> proving that our RUInt32 generator type works.
>>
>> How is this related to RUint32?
> 
> Typo in the commit message; this should be RUInt64.  Oh well, the
> commit is already in.
> 
>>
>>>
>>> This commit is also a showcase of whether I can do 64-bit math in
>>> various languages (C's terseness in 'a == b + (c > d)' is annoying to
>>> replicate in languages that don't like playing fast and loose with
>>> types).  :)
>>
>> I don't understand; please elaborate.
> 
> Sure. In C, uint64_t == uint64_t + bool is legal; making for a nice
> terse expression.

I interpreted your statement about 64-bit math and the formula

  a == b + (c > d)

as if the formula were some means to implement *64-bit-safe* math (addition, 
overflow etc something like that). I understood how the expression worked at 
the lowest level, but didn't understand what it was good for -- what it 
expressed.

The more concrete form is

  cr3 == cr2 + (br3 > br2)

which seems to stand for: "chunks received #3" should equal "chunks received 
#2, plus one chunk, if we received additional bytes (in br3) since setting br2".

Basically the section

+bs2 = h.stats_bytes_sent()
+cs2 = h.stats_chunks_sent()
+br2 = h.stats_bytes_received()
+cr2 = h.stats_chunks_received()
+
+[...]
+
+# Stats are still readable after the connection closes; we don't know if
+# the server sent reply bytes to our NBD_CMD_DISC, so don't insist on it.
+h.shutdown()
+
+bs3 = h.stats_bytes_sent()
+cs3 = h.stats_chunks_sent()
+br3 = h.stats_bytes_received()
+cr3 = h.stats_chunks_received()
+
+assert bs3 > bs2
+assert cs3 == cs2 + 1
+assert br3 >= br2
+assert cr3 == cr2 + (br3 > br2)

was a bit too hard for me to parse. I didn't notice the role of h.shutdown() 
before.

Acked-by: Laszlo Ersek <ler...@redhat.com>


> 
>>> +++ b/python/t/620-stats.py
> 
>>> +# Stats are still readable after the connection closes; we don't know if
>>> +# the server sent reply bytes to our NBD_CMD_DISC, so don't insist on it.
>>> +h.shutdown()
>>> +
>>> +bs3 = h.stats_bytes_sent()
>>> +cs3 = h.stats_chunks_sent()
>>> +br3 = h.stats_bytes_received()
>>> +cr3 = h.stats_chunks_received()
>>> +
>>> +assert bs3 > bs2
>>> +assert cs3 == cs2 + 1
>>> +assert br3 >= br2
>>> +assert cr3 == cr2 + (br3 > br2)
> 
> And in python.
> 
>>> +++ b/ocaml/tests/test_620_stats.ml
>>> +  (* Stats are still readable after the connection closes; we don't know if
>>> +   * the server sent reply bytes to our NBD_CMD_DISC, so don't insist on 
>>> it.
>>> +   *)
>>> +  NBD.shutdown nbd;
>>> +
>>> +  let bs3 = NBD.stats_bytes_sent nbd in
>>> +  let cs3 = NBD.stats_chunks_sent nbd in
>>> +  let br3 = NBD.stats_bytes_received nbd in
>>> +  let cr3 = NBD.stats_chunks_received nbd in
>>> +  let fudge = if cr2 = cr3 then 0L else 1L in
>>> +  assert (bs3 > bs2);
>>> +  assert (cs3 = (Int64.succ cs2));
>>> +  assert (br3 >= br2);
>>> +  assert (cr3 = (Int64.add cr2 fudge))
> 
> Not so in OCaml, where + isn't even polymorphic to int64, so I have to
> break out manual calls to Int64.XXX methods.  Here, I went with a
> helper variable 'fudge'.
> 
>>> +++ b/golang/libnbd_620_stats.go
>>> +   /* Stats are still readable after the connection closes; we don't know 
>>> if
>>> +    * the server sent reply bytes to our NBD_CMD_DISC, so don't insist on 
>>> it.
>>> +    */
>>> +   err = h.Shutdown(nil)
>>> +   if err != nil {
>>> +           t.Fatalf("%s", err)
>>> +   }
>>> +
>>> +   bs3, err := h.StatsBytesSent()
>>> +   if err != nil {
>>> +           t.Fatalf("%s", err)
>>> +   }
>>> +   cs3, err := h.StatsChunksSent()
>>> +   if err != nil {
>>> +           t.Fatalf("%s", err)
>>> +   }
>>> +   br3, err := h.StatsBytesReceived()
>>> +   if err != nil {
>>> +           t.Fatalf("%s", err)
>>> +   }
>>> +   cr3, err := h.StatsChunksReceived()
>>> +   if err != nil {
>>> +           t.Fatalf("%s", err)
>>> +   }
>>> +   slop := uint64(1)
>>> +   if br2 == br3 {
>>> +           slop = uint64(0)
>>> +   }
>>> +
>>> +   if bs3 <= bs2 {
>>> +           t.Fatalf("unexpected value for bs3")
>>> +   }
>>> +   if cs3 != cs2 + 1 {
>>> +           t.Fatalf("unexpected value for cs3")
>>> +   }
>>> +   if br3 < br2 {
>>> +           t.Fatalf("unexpected value for br3")
>>> +   }
>>> +   if cr3 != cr2 + slop {
>>> +           t.Fatalf("unexpected value for cr3")
>>> +   }
> 
> Nor in Go, where you can't even do uint64(bool), but HAVE to use an
> 'if' statement to populate 'slop' with the correct value.  Hmm, maybe
> I should have used the same variable name between OCaml and Go,
> instead of 'slop'/'fudge'; oh well.  (And Go is painfully verbose in
> the amount of boilerplate formatting it requires, compared to the
> other languages; although I will be the first to admit that I'm
> probably not an idiomatic Go coder)
> 

_______________________________________________
Libguestfs mailing list
Libguestfs@redhat.com
https://listman.redhat.com/mailman/listinfo/libguestfs

Reply via email to