unofficial mirror of guix-patches@gnu.org 
 help / color / mirror / code / Atom feed
From: Bruno Victal <mirai@makinata.eu>
To: "Ludovic Courtès" <ludo@gnu.org>
Cc: maxim.cournoyer@gmail.com, 60788@debbugs.gnu.org
Subject: [bug#60788] [PATCH] services: Add vnstat-service-type.
Date: Sat, 8 Apr 2023 13:40:39 +0100	[thread overview]
Message-ID: <07feadac-18b2-7e82-9798-3e3872efcd4a@makinata.eu> (raw)
In-Reply-To: <87edovd8em.fsf_-_@gnu.org>

Hi  Ludo’,

On 2023-04-07 16:22, Ludovic Courtès wrote:
> I think a system test would be nice, we generally require it upfront,
> but since Maxim wrote it can come later, let’s not let it block this
> patch any longer.

Originally I thought it was unfeasible to write a test for this service
since it required network activity within the VM and it seemed to take more
than 10 minutes for it to pick it up.

I did some manual experiments on it much later and I managed to get it down to
approx. between 2 and 3 minutes for a partially automated test.

What's blocking the test from being implemented in Guix is that my (incomplete) test-suite
for this depends on guile 'spawn', which isn't available yet,
For reference, I've attached the test-suite here [1], the plan is to finish it up and
add it to Guix after the 'spawn' issue is resolved. (or perhaps refactor this to use another approach?)

> 
> One comment:
> 
>> +@item @code{database-dir} (default: @code{"/var/lib/vnstat"}) (type: string)
> 
> [...]
> 
>> +@item @code{create-dirs?} (default: @code{#t}) (type: maybe-boolean)
> 
> For consistency, both within this record and with the rest of Guix, I
> suggest avoiding abbreviations.  Since this will be part of the API,
> better fix it now than later.

I should mention that almost all of the field names here are near verbatim
vnstat config-file directives, i.e. a near 1-1 Scheme translation of vnstat config.
This has the benefit that it makes serialization pretty much straightforward.

It's possible to override their names by the use of the custom serializer parameter
but would it be acceptable to leave them as-is?

>> +@item @code{max-bandwidth} (type: maybe-integer)
>> +Maximum bandwidth for all interfaces.  If the interface specific traffic
>> +exceeds the given value then the data is assumed to be invalid and
>> +rejected.  Set to 0 in order to disable the feature.  Value range:
>> +@samp{0}..@samp{50000}
>> +
>> +@item @code{max-bw} (type: maybe-alist)
>> +Same as @var{max-bandwidth} but can be used for setting individual
>> +limits for selected interfaces.  This is an association list of
>> +interfaces as symbols/strings to integer values.  For example,
>> +@lisp
>> +(max-bw `((eth0 .  15000)
>> +          (ppp0 .  10000)))
>> +@end lisp
> 
> Both the naming and semantics are a bit confusing to me.
> 
> How about s/max-bw/per-interface-max-bandwidth/ ?

I found it a bit confusing as well but I'm not too familiar with this part of
the config to comment about it.
I lifted most of the field-names and documentations straight from the manpage.

> Side note: I’d represent interfaces as strings because there’s no
> guarantee they “fit” in a symbol.

Thanks! I'll have this amended in the next revision.


[1]: Listing of vnstat-test.scm

--8<---------------cut here---------------start------------->8---
(define-module (gnu tests vnstat)
  #:use-module (gnu tests)
  #:use-module ((gnu packages networking) #:select (socat vnstat))
  #:use-module (gnu services)
  #:use-module (gnu services networking)
  #:use-module (gnu services monitoring)
  #:use-module (gnu system)
  #:use-module (gnu system vm)
  #:use-module (guix gexp)
  #:use-module (ice-9 format)
  #:export (%test-vnstat))


(define (run-vnstat-test)
  "Run tests in a vm which has vnstat running."

  (define vnstat-config
    (vnstat-configuration
     (max-bandwidth 0)
     (time-sync-wait 0)
     (bandwidth-detection-interval 0)))

  (define os
    (marionette-operating-system
     (simple-operating-system
      (service dhcp-client-service-type)
      (service vnstat-service-type
               vnstat-config)
      (service inetd-service-type
               (inetd-configuration
                (entries
                 (list (inetd-entry
                        (name "discard")
                        (socket-type 'stream)
                        (protocol "tcp")   ;; FIXME: originally this was UDP but port-forwardings hardcodes TCP
                        (wait? #t)
                        (user "nobody")))))))
     #:imported-modules '((gnu services herd))))

  (define forwarded-port 9999)

  (define vm
    (virtual-machine
     (operating-system os)
     ;; Note: port 9 corresponds to "discard" service.
     (port-forwardings `((,forwarded-port . 9)))))   ;; FIXME: Allow UDP forward.

  (define test-timeout (* 60 2))  ; wait for 2 minutes tops.

  (define test
    (with-imported-modules '((gnu build marionette))
      #~(begin
          (use-modules (gnu build marionette)
                       (srfi srfi-64))

          (let ((marionette (make-marionette (list #$vm)))
                (pid-file #$(vnstat-configuration-pid-file vnstat-config)))

            (test-runner-current (system-test-runner #$output))
            (test-begin "vnstat")

            (test-assert "service is running"
              (marionette-eval
               '(begin
                  (use-modules (gnu services herd))
                  (start-service 'vnstatd))
               marionette))

            (test-assert "vnstatd ready"
              (wait-for-file pid-file marionette))

            (test-assert "vnstatd is logging"
              ;; pump garbage into the "discard" service within the vm
              ;; TODO: guile socket client instead? Is it feasible?
              (let* ((socat #$(file-append socat "/bin/socat"))
                     (dest-addr #$(format #f "TCP4:localhost:~d"
                                          forwarded-port))
                     (args `("socat" "-u" "/dev/zero" ,dest-addr))
                     ;; XXX: Guile bug (22/03/2023, Guile 3.0.9)
                     ;;      Fixed in main: <https://issues.guix.gnu.org/61073>
                     #;(output-port (%make-void-port "w"))
                     (garbage-pump-pid (spawn socat args)))

                (let ((retval
                       (marionette-eval
                        '(begin
                           (use-modules (ice-9 popen)
                                        ;(ice-9 rdelim)
                                        (ice-9 match)
                                        (sxml simple)
                                        (sxml xpath))

                           (define selector
                             (let ((xpath '(vnstat interface traffic total)))
                               (compose (node-pos 1) (sxpath xpath))))

                           (let loop ((i 0))
                             (let* ((vnstat #$(file-append vnstat "/bin/vnstat"))
                                    (query-cmd (format #f "~a --xml") vnstat)
                                    (result
                                     #;(call-with-port
                                     (open-input-pipe query-cmd) read-line)
                                     (call-with-port
                                         (open-input-pipe query-cmd) xml->sxml))
                                    (iface-stats (selector result)))
                               (match iface-stats
                                 ((('total ('rx "0") ('tx "0")))
                                  (sleep 1)
                                  (if (< i #$test-timeout)
                                      (loop (+ i 1))
                                      #f))
                                 ((('total ('rx rx) ('tx tx)))
                                  #t)
                                 (_ #f)))))
                        marionette)))
                  ;; shutdown garbage pump
                  (kill garbage-pump-pid SIGTERM)
                  retval)))

            (test-end)))))

  (gexp->derivation "vnstat-test" test))

(define %test-vnstat
  (system-test
   (name "vnstat")
   (description "Basic tests for vnstat service.")
   (value (run-vnstat-test))))
--8<---------------cut here---------------end--------------->8---


Cheers,
Bruno




  parent reply	other threads:[~2023-04-08 12:41 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-13 20:07 [bug#60788] [PATCH] services: Add vnstat-service-type Bruno Victal
2023-01-14 21:06 ` [bug#60788] [PATCH v2] " Bruno Victal
2023-01-16 18:42 ` [bug#60788] [PATCH] " Maxim Cournoyer
2023-01-16 19:31   ` Bruno Victal
2023-01-16 19:56     ` Maxim Cournoyer
2023-01-18  0:34 ` [bug#60788] [PATCH v2] " Bruno Victal
2023-01-18  0:37 ` [bug#60788] [PATCH v2] services: vnstat: Use least-authority-wrapper Bruno Victal
2023-02-02 14:21 ` [bug#60788] [PATCH v3] services: Add vnstat-service-type Bruno Victal
2023-02-07 14:25 ` [bug#60788] [PATCH v4] " Bruno Victal
2023-02-09  3:34   ` [bug#60788] [PATCH] " Maxim Cournoyer
2023-02-09  4:19     ` Bruno Victal
2023-02-09 13:31       ` Maxim Cournoyer
2023-02-10 13:15 ` [bug#60788] [PATCH v5] " Bruno Victal
2023-02-10 14:07   ` Maxim Cournoyer
2023-02-10 14:14 ` [bug#60788] [PATCH v6] " Bruno Victal
2023-03-22 16:15 ` [bug#60788] [PATCH v7] " Bruno Victal
2023-04-03 14:14 ` [bug#60788] [PATCH v8] " Bruno Victal
2023-04-04 13:08 ` [bug#60788] [PATCH v9] " Bruno Victal
2023-04-07 15:22   ` [bug#60788] [PATCH] " Ludovic Courtès
2023-04-07 20:04     ` Maxim Cournoyer
2023-04-20 10:03       ` [bug#60788] Policy for system tests? Ludovic Courtès
2023-04-08 12:40     ` Bruno Victal [this message]
2023-04-20 10:09       ` [bug#60788] [PATCH] services: Add vnstat-service-type Ludovic Courtès
2023-05-05  0:18 ` [bug#60788] [PATCH v10 1/3] " Bruno Victal
2023-05-11 14:33   ` bug#60788: " Ludovic Courtès
2023-05-05  0:18 ` [bug#60788] [PATCH v10 2/3] services: inetd: Export accessors Bruno Victal
2023-05-05  0:18 ` [bug#60788] [PATCH v10 3/3] tests: Add vnstat tests Bruno Victal

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://guix.gnu.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=07feadac-18b2-7e82-9798-3e3872efcd4a@makinata.eu \
    --to=mirai@makinata.eu \
    --cc=60788@debbugs.gnu.org \
    --cc=ludo@gnu.org \
    --cc=maxim.cournoyer@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).