b2f183829c143cba0dc29c91b6964925bde406f2
[cascardo/ovs.git] / tests / test-ovn.c
1 /*
2  * Copyright (c) 2015 Nicira, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <config.h>
18 #include "command-line.h"
19 #include <getopt.h>
20 #include "dynamic-string.h"
21 #include "fatal-signal.h"
22 #include "match.h"
23 #include "ovn/lib/lex.h"
24 #include "ovstest.h"
25 #include "util.h"
26 #include "openvswitch/vlog.h"
27
28 static void
29 compare_token(const struct lex_token *a, const struct lex_token *b)
30 {
31     if (a->type != b->type) {
32         fprintf(stderr, "type differs: %d -> %d\n", a->type, b->type);
33         return;
34     }
35
36     if (!((a->s && b->s && !strcmp(a->s, b->s))
37           || (!a->s && !b->s))) {
38         fprintf(stderr, "string differs: %s -> %s\n",
39                 a->s ? a->s : "(null)",
40                 b->s ? b->s : "(null)");
41         return;
42     }
43
44     if (a->type == LEX_T_INTEGER || a->type == LEX_T_MASKED_INTEGER) {
45         if (memcmp(&a->value, &b->value, sizeof a->value)) {
46             fprintf(stderr, "value differs\n");
47             return;
48         }
49
50         if (a->type == LEX_T_MASKED_INTEGER
51             && memcmp(&a->mask, &b->mask, sizeof a->mask)) {
52             fprintf(stderr, "mask differs\n");
53             return;
54         }
55
56         if (a->format != b->format
57             && !(a->format == LEX_F_HEXADECIMAL
58                  && b->format == LEX_F_DECIMAL
59                  && a->value.integer == 0)) {
60             fprintf(stderr, "format differs: %d -> %d\n",
61                     a->format, b->format);
62         }
63     }
64 }
65
66 static void
67 test_lex(struct ovs_cmdl_context *ctx OVS_UNUSED)
68 {
69     struct ds input;
70     struct ds output;
71
72     ds_init(&input);
73     ds_init(&output);
74     while (!ds_get_line(&input, stdin)) {
75         struct lexer lexer;
76
77         lexer_init(&lexer, ds_cstr(&input));
78         ds_clear(&output);
79         while (lexer_get(&lexer) != LEX_T_END) {
80             size_t len = output.length;
81             lex_token_format(&lexer.token, &output);
82
83             /* Check that the formatted version can really be parsed back
84              * losslessly. */
85             if (lexer.token.type != LEX_T_ERROR) {
86                 const char *s = ds_cstr(&output) + len;
87                 struct lexer l2;
88
89                 lexer_init(&l2, s);
90                 lexer_get(&l2);
91                 compare_token(&lexer.token, &l2.token);
92                 lexer_destroy(&l2);
93             }
94             ds_put_char(&output, ' ');
95         }
96         lexer_destroy(&lexer);
97
98         ds_chomp(&output, ' ');
99         puts(ds_cstr(&output));
100     }
101     ds_destroy(&input);
102     ds_destroy(&output);
103 }
104
105 static void
106 test_ovn_main(int argc, char *argv[])
107 {
108     set_program_name(argv[0]);
109
110     static const struct ovs_cmdl_command commands[] = {
111         {"lex", NULL, 0, 0, test_lex},
112         {NULL, NULL, 0, 0, NULL},
113     };
114     struct ovs_cmdl_context ctx;
115     ctx.argc = argc - optind;
116     ctx.argv = argv + optind;
117     ovs_cmdl_run_command(&ctx, commands);
118 }
119
120 OVSTEST_REGISTER("test-ovn", test_ovn_main);