# How to simulate the "Command Timed out" while provisioning?

**URL:** https://dmap-community.ductus.global/t/how-to-simulate-the-command-timed-out-while-provisioning/2830
**Category:** CDB and CDB API
**Created:** [December 16, 2019, 7:53pm UTC](https://dmap-community.ductus.global/t/how-to-simulate-the-command-timed-out-while-provisioning/2830 "2019-12-16T19:53:56Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![sachinsr](https://avatars.discourse-cdn.com/v4/letter/s/46a35a/32.png) [@sachinsr](https://dmap-community.ductus.global/u/sachinsr)
#### Post date: [December 16, 2019, 7:53pm UTC](https://dmap-community.ductus.global/t/how-to-simulate-the-command-timed-out-while-provisioning/2830/1 "2019-12-16T19:53:56Z")

</div>

I want to simulate a negative scenario while provisioning some commands on configuration mode.

_Ex: “Command Timed out.”_

The way I have implemented now is connecting and subscribing to cdb for a particular container/leaf. (In my case its /system/contact) and then try to provision one of the command with commit. The Network device has to wait for an indefinite amount of time, after that it should fail with “Command Time out”.

_ **Actual Behaviour:** _

> admin@NE-1% set system contact abc  
> [edit]  
> admin@NE-1% commit  
> Commit complete.

_ **Expected Behaviour:** _

> admin@NE-1% set system contact abc  
> [edit]  
> admin@NE-1% commit  
> Command Timed out

_ **The solution I tried:** _

I tried decreasing the queryTimeout in confd.conf

```
 <capi>
       <newSessionTimeout>PT120S</newSessionTimeout>
        <queryTimeout>PT120S</queryTimeout>
 </capi>

```

and Increasing the wait time after commit on the device (sleep(600)) to be more than queryTimeout.

_ **Code snippet:** _

> #include \<sys/types.h\>  
> #include \<sys/socket.h\>  
> #include \<netinet/in.h\>  
> #include \<arpa/inet.h\>  
> #include \<sys/poll.h\>  
> #include \<string.h\>  
> #include \<stdlib.h\>  
> #include \<stdio.h\>  
> #include \<unistd.h\>  
> #include \<sys/time.h\>  
> #include \<time.h\>  
> #include \<string.h\>  
> #include \<errno.h\>  
> #include \<ctype.h\>  
> #include \<system.h\>  
> #ifndef MAX\_ARGS  
> #define MAX\_ARGS 32  
> #endif
> 
> #ifndef BUFSIZ  
> #define BUFSIZ 1024  
> #endif
> 
> /_CONFD and custom libraries_/
> 
> #include \<confd\_lib.h\>  
> #include \<confd\_dp.h\>  
> #include \<confd\_cdb.h\>  
> #include \<confd\_maapi.h\>  
> #include \<confd\_cdb.h\>
> 
> /\* Our daemon context as a global variable \*/
> 
> static struct confd\_daemon\_ctx \*dctx;  
> struct listElement \*list\_map = NULL;  
> int debuglevel = CONFD\_SILENT;
> 
> int main(int argc, char \*argv){
> 
> ```
> struct sockaddr_in addr;
> int debuglevel = CONFD_SILENT;
> int subsock;
> int status;
> int spoint;
> confd_init("cdb_listen_att", stderr, debuglevel);
> addr.sin_addr.s_addr = inet_addr("127.0.0.1");
> addr.sin_family = AF_INET;
> addr.sin_port = htons(CONFD_PORT);
> 
> if (confd_load_schemas((struct sockaddr*)&addr, sizeof (struct sockaddr_in)) != CONFD_OK) {
> confd_fatal("Failed to load schemas from confd\n");
> }
> 
> if ((dctx = confd_init_daemon("cdb_listen_att")) == NULL){
> confd_fatal("Failed to initialize confdlib\n");
> }
> 
> if ((subsock = socket(PF_INET, SOCK_STREAM, 0)) < 0 ) {
> confd_fatal("Failed to open ctlsocket\n");
> }
> 
> if (cdb_connect(subsock, CDB_SUBSCRIPTION_SOCKET, (struct sockaddr*)&addr,
> sizeof (struct sockaddr_in)) < 0)
> confd_fatal("Sub: Failed to cdb_connect() to confd \n");
> 
> if ((status = cdb_subscribe(subsock, 3, sys_ns, &spoint, "/system/contact/"))
> != CONFD_OK) {
> fprintf(stderr, "Terminate: subscribe %d\n", status);
> exit(0);
> }
> if (cdb_subscribe_done(subsock) != CONFD_OK)
> confd_fatal("cdb_subscribe_done() failed");
> printf("Subscription point = %d\n", spoint);
> 
> while (1) {
> struct pollfd set[1];
> 
> set[0].fd = subsock;
> set[0].events = POLLIN;
> set[0].revents = 0;
> 
> if (poll(set, sizeof(set)/sizeof(*set), -1) < 0) {
> perror("Poll failed:");
> continue;
> }
> else{
> printf("Wait Time for the Command Timeout\n");
> sleep(600);
> }
> /* Check for I/O */
> if (set[0].revents & POLLIN) {
> int sub_points[1];
> int reslen;
> if ((status = cdb_read_subscription_socket(subsock,
> &sub_points[0],
> &reslen)) != CONFD_OK)
> exit(status);
> 
> if ((status = cdb_sync_subscription_socket(subsock,
> CDB_DONE_PRIORITY))
> != CONFD_OK) {
> exit(status);
> }
> }
> }
> 
> ```
> 
> }

_yang for system :_

> container system {  
> description  
> “System related configurations”;  
> leaf contact {  
> type string;  
> description  
> “Contact information for this system”;  
> }  
> }

P.S: You can use any provisioning command. To reproduce in your setup. the only line you need to change in code snippet is.

> if ((status = cdb\_subscribe(subsock, 3, sys\_ns, &spoint, “/system/contact/”))

change the namespace and the container/leaf where the delay should happen for commit, eventually occurring Command Timed out.

---

<div class="post-metadata">

### Author: ![cohult](https://yyz2.discourse-cdn.com/flex010/user_avatar/dmap-community.ductus.global/cohult/32/221_2.png) [@cohult](https://dmap-community.ductus.global/u/cohult)
#### Post date: [December 16, 2019, 11:21pm UTC](https://dmap-community.ductus.global/t/how-to-simulate-the-command-timed-out-while-provisioning/2830/2 "2019-12-16T23:21:42Z")

</div>

See:  
`int cdb_set_timeout(int sock, int timeout_secs);`  
in the confd\_lib\_cdb(3) man pages, and:  
`/confdConfig/cdb/clientTimeout`  
in the confd.conf(5) man pages.

More of the same in this post from a few years back:

> [@Is there a way to control the CDB client timeout interval?](http://dmap-community.ductus.global/t/is-there-a-way-to-control-the-cdb-client-timeout-interval/131?u):
>
> The following parameter in confd.conf can be used to specify the CDB client timeout interval: /confdConfig/cdb/clientTimeout (xs:duration|infinity) [infinity] When left unspecified, it defaults to infinity. CDB will never timeout waiting for a response from a client. A client which doesn’t respond will have its socket closed. Otherwise, clientTimeout specifies how long CDB should wait while a client performs a certain action, before considering that client unresponsive. The timeout is appli…

---

<div class="post-metadata">

### Author: ![per](https://avatars.discourse-cdn.com/v4/letter/p/9f8e36/32.png) [@per](https://dmap-community.ductus.global/u/per)
#### Post date: [December 17, 2019, 2:17pm UTC](https://dmap-community.ductus.global/t/how-to-simulate-the-command-timed-out-while-provisioning/2830/3 "2019-12-17T14:17:18Z")

</div>

A “normal” (i.e. not using `CDB_SUB_RUNNING_TWOPHASE` with `cdb_subscribe2()`) CDB subscriber is notified when the changes have already been committed to CDB, it can’t affect the success of the commit, only the time it takes to complete. The timeout that @cohult mentions is the way to protect against a “misbehaving” subscriber, but the commit will succeed even if the timeout fires.

---

<div class="post-metadata">

### Author: ![sachinsr](https://avatars.discourse-cdn.com/v4/letter/s/46a35a/32.png) [@sachinsr](https://dmap-community.ductus.global/u/sachinsr)
#### Post date: [December 18, 2019, 2:29am UTC](https://dmap-community.ductus.global/t/how-to-simulate-the-command-timed-out-while-provisioning/2830/4 "2019-12-18T02:29:06Z")

</div>

Hi @cohult,

Does this mean I need to use

> int cdb\_set\_timeout(int sock, int timeout\_secs);

in my code ? If Yes where do I need to use it.

I tried

> /confdConfig/cdb/clientTimeout

by setting it to 100 seconds and then increasing the sleep to be more than 100 seconds in my code for it to fail with Time out ,but that didn’t work.

Thanks,  
Sachin Siddappa

---

<div class="post-metadata">

### Author: ![sachinsr](https://avatars.discourse-cdn.com/v4/letter/s/46a35a/32.png) [@sachinsr](https://dmap-community.ductus.global/u/sachinsr)
#### Post date: [December 18, 2019, 2:31am UTC](https://dmap-community.ductus.global/t/how-to-simulate-the-command-timed-out-while-provisioning/2830/5 "2019-12-18T02:31:59Z")

</div>

HI @per,

Can you elaborate what needs to be done, as I am still in a learning phase.  
Anything with the example would greatly help my understanding to the concept.

Thanks,  
Sachin Siddappa

---

<div class="post-metadata">

### Author: ![cohult](https://yyz2.discourse-cdn.com/flex010/user_avatar/dmap-community.ductus.global/cohult/32/221_2.png) [@cohult](https://dmap-community.ductus.global/u/cohult)
#### Post date: [December 18, 2019, 10:33am UTC](https://dmap-community.ductus.global/t/how-to-simulate-the-command-timed-out-while-provisioning/2830/6 "2019-12-18T10:33:25Z")

</div>

An example based on the examples.confd/cdb\_subscribe/twophase example:

```bash
$ pwd
/Users/tailf/confd-7.3/examples.confd/cdb_subscription/twophase
$ cat confd.conf |grep clientTimeout
  <clientTimeout>PT20S</clientTimeout>
  <!-- <clientTimeout>infinity</clientTimeout> -->
$ diff -u twophase.c.orig twophase.c
--- twophase.c.orig
+++ twophase.c
@@ -164,6 +164,7 @@
     int di = 1;
     int di_schema_order = 0;
     char *gp = NULL;
+ int st = 0;
 
     /* Setup progname (without path component) */
     if ((progname = strrchr(argv[0], (int)'/')) == NULL)
@@ -181,7 +182,7 @@
     }
 
     /* Parse command line */
- while ((c = getopt(argc, argv, "da:p:intr:o:semfg:")) != EOF) {
+ while ((c = getopt(argc, argv, "da:p:g:s:")) != EOF) {
         switch (c) {
         case 'd':
           debug++;
@@ -195,6 +196,9 @@
         case 'g':// try to Get path after notification
           gp = optarg;
           break;
+ case 's':
+ st = atoi(optarg);
+ break;
         default:
           exit(1);
         }
@@ -279,6 +283,7 @@
           res = cdb_read_subscription_socket2(ss, &type, &flags, &subp, &len);
 
           if (res == CONFD_EOF) {
+ fprintf(stderr, "ConfD closed the subscriber socket. Exit...\n");
             exit(0);
           }
           OK(res);
@@ -299,6 +304,7 @@
             case CDB_SUB_PREPARE:
               printf("\nTYPE=CDB_SUB_PREPARE\n");
               {
+ if (st) { printf("sleep %d seconds\n", st); sleep(st); }
                 if (di) call_diff_iterate(ss, "diff prepare", subp, len,
                                           di_schema_order);
                 if (gp) pget(gp, 0);
$ make all hardware_up
...
$ confd -c confd.conf --addloadpath $CONFD_DIR/etc/confd
$ ./twophase -s21 /system &
$ time netconf-console --edit-config=-<<<'<system xmlns="http://tail-f.com/ns/example/config"><nodes><name>some_name</name></nodes></system>'

recv notification PREPARE flags=LAST subids=7 

TYPE=CDB_SUB_PREPARE
sleep 21 seconds
<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="1">
  <rpc-error>
    <error-type>application</error-type>
    <error-tag>operation-failed</error-tag>
    <error-severity>error</error-severity>
    <error-message xml:lang="en">application communication failure</error-message>
  </rpc-error>
</rpc-reply>

real	0m20.592s
user	0m0.224s
sys	0m0.071s
send CDB_DONE_PRIORITY
ConfD closed the subscriber socket. Exit...

```

In the twophase.c example, note that the transaction will only fail if we are in the prepare phase of the transaction (as @per pointed out above) and a mandatory subscriber fail to reply, for example before the client timeout expire.
