Statistics
| Branch: | Revision:

grapes / src / Tests / topology_test_attr.c @ 534e126a

History | View | Annotate | Download (4.93 KB)

1
/*
2
 *  Copyright (c) 2009 Luca Abeni
3
 *
4
 *  This is free software; see gpl-3.0.txt
5
 *
6
 *  This is a small test program for the gossip based TopologyManager
7
 *  To try the simple test: run it with
8
 *    ./topology_test -I <network interface> -P <port> [-i <remote IP> -p <remote port>]
9
 *    the "-i" and "-p" parameters can be used to add an initial neighbour
10
 *    (otherwise, the peer risks to stay out of the overlay).
11
 *    For example, run
12
 *      ./topology_test -I eth0 -P 6666
13
 *    on a computer, and then
14
 *      ./topology_test -I eth0 -P 2222 -i <ip_address> -p 6666
15
 *  on another one ... Of course, one of the two peers has to use -i... -p...
16
 *  (in general, to be part of the overlay a peer must either use
17
 *  "-i<known peer IP> -p<known peer port>" or be referenced by another peer).
18
 */
19
#include <stdlib.h>
20
#include <stdint.h>
21
#include <stdio.h>
22
#include <string.h>
23
#include <getopt.h>
24

    
25
#include "net_helper.h"
26
#include "peersampler.h"
27
#include "net_helpers.h"
28

    
29
static struct psample_context *context;
30
static const char *my_addr = "127.0.0.1";
31
static int port = 6666;
32
static int srv_port;
33
static const char *srv_ip;
34

    
35
static struct peer_attributes {
36
  enum peer_state {sleep, awake, tired} state;
37
  char colour[20];
38
  char name[40];
39
} my_attr;
40

    
41
static void cmdline_parse(int argc, char *argv[])
42
{
43
  int o;
44

    
45
  my_attr.state = awake;
46
  sprintf(my_attr.colour, "red");
47
  while ((o = getopt(argc, argv, "p:i:P:I:c:ST")) != -1) {
48
    switch(o) {
49
      case 'p':
50
        srv_port = atoi(optarg);
51
        break;
52
      case 'i':
53
        srv_ip = strdup(optarg);
54
        break;
55
      case 'P':
56
        port =  atoi(optarg);
57
        break;
58
      case 'I':
59
        my_addr = iface_addr(optarg);
60
        break;
61
      case 'c':
62
        strcpy(my_attr.colour, optarg);
63
        break;
64
      case 'S':
65
        my_attr.state = sleep;
66
        break;
67
      case 'T':
68
        my_attr.state = tired;
69
        break;
70
      default:
71
        fprintf(stderr, "Error: unknown option %c\n", o);
72

    
73
        exit(-1);
74
    }
75
  }
76
}
77

    
78
static struct nodeID *init(void)
79
{
80
  struct nodeID *myID;
81
  char addr[256];
82

    
83
  myID = net_helper_init(my_addr, port, "");
84
  if (myID == NULL) {
85
    fprintf(stderr, "Error creating my socket (%s:%d)!\n", my_addr, port);
86

    
87
    return NULL;
88
  }
89

    
90
  node_addr(myID, addr, 256);
91
  strcpy(my_attr.name, addr);
92
  context = psample_init(myID, &my_attr, sizeof(struct peer_attributes), "");
93

    
94
  return myID;
95
}
96

    
97
static const char *status_print(enum peer_state s)
98
{
99
  switch (s) {
100
    case sleep:
101
      return "sleeping";
102
    case awake:
103
      return "awake";
104
    case tired:
105
      return "tired";
106
    default:
107
      return "Boh?";
108
  }
109
}
110

    
111
static void status_update(void)
112
{
113
  struct nodeID *myself;
114

    
115
  switch (my_attr.state) {
116
    case sleep:
117
      my_attr.state = awake;
118
      break;
119
    case awake:
120
      my_attr.state = tired;
121
      break;
122
    case tired:
123
      my_attr.state = sleep;
124
      break;
125
  }
126
  printf("goin' %s\n", status_print(my_attr.state));
127
  myself = create_node(my_addr, port);
128
  psample_change_metadata(context, &my_attr, sizeof(struct peer_attributes));
129
  nodeid_free(myself);
130
}
131

    
132
static void loop(struct nodeID *s)
133
{
134
  int done = 0;
135
#define BUFFSIZE 1024
136
  static uint8_t buff[BUFFSIZE];
137
  char addr[256];
138
  int cnt = 0;
139

    
140
  psample_parse_data(context, NULL, 0);
141
  while (!done) {
142
    int len;
143
    int news;
144
    struct timeval tout = {1, 0};
145

    
146
    news = wait4data(s, &tout, NULL);
147
    if (news > 0) {
148
      struct nodeID *remote;
149

    
150
      len = recv_from_peer(s, &remote, buff, BUFFSIZE);
151
      psample_parse_data(context, buff, len);
152
      nodeid_free(remote);
153
    } else {
154
      if (cnt % 30 == 0) {
155
        status_update();
156
      }
157
      psample_parse_data(context, NULL, 0);
158
      if (cnt++ % 10 == 0) {
159
        const struct nodeID **neighbourhoods;
160
        int n, i, size;
161
        const struct peer_attributes *meta;
162

    
163
        neighbourhoods = psample_get_cache(context, &n);
164
        meta = psample_get_metadata(context, &size);
165
        if (meta == NULL) {
166
          printf("No MetaData!\n");
167
        } else {
168
          if (size != sizeof(struct peer_attributes)) {
169
            fprintf(stderr, "Bad MetaData!\n");
170
            exit(-1);
171
          }
172
        }
173
        printf("I have %d neighbourhoods:\n", n);
174
        for (i = 0; i < n; i++) {
175
          node_addr(neighbourhoods[i], addr, 256);
176
          printf("\t%d: %s", i, addr);
177
          if (meta) {
178
            printf("\tPeer %s is a %s peer and is %s", meta[i].name, meta[i].colour, status_print(meta[i].state));
179
          }
180
          printf("\n");
181
        }
182
      }
183
    }
184
  }
185
}
186

    
187
int main(int argc, char *argv[])
188
{
189
  struct nodeID *my_sock;
190

    
191
  cmdline_parse(argc, argv);
192

    
193
  my_sock = init();
194
  if (my_sock == NULL) {
195
    return -1;
196
  }
197

    
198
  if (srv_port != 0) {
199
    struct nodeID *knownHost;
200

    
201
    knownHost = create_node(srv_ip, srv_port);
202
    if (knownHost == NULL) {
203
      fprintf(stderr, "Error creating knownHost socket (%s:%d)!\n", srv_ip, srv_port);
204

    
205
      return -1;
206
    }
207
    psample_add_peer(context, knownHost, NULL, 0);
208
  }
209

    
210
  loop(my_sock);
211

    
212
  return 0;
213
}