xref: /haiku/src/tests/add-ons/kernel/file_systems/bfs/queries/test.cpp (revision e81a954787e50e56a7f06f72705b7859b6ab06d1)
1 #include <Message.h>
2 #include <Entry.h>
3 #include <File.h>
4 #include <NodeMonitor.h>
5 #include <kernel/fs_info.h>
6 #include <kernel/fs_query.h>
7 
8 #include <stdio.h>
9 #include <string.h>
10 
11 #ifndef B_BAD_DATA
12 #	define B_BAD_DATA B_ERROR
13 #endif
14 
15 #define DUMPED_BLOCK_SIZE 16
16 #define Print printf
17 
18 void
19 dumpBlock(const char *buffer,int size)
20 {
21 	for(int i = 0;i < size;) {
22 		int start = i;
23 
24 		for(;i < start+DUMPED_BLOCK_SIZE;i++) {
25 			if (!(i % 4))
26 				Print(" ");
27 
28 			if (i >= size)
29 				Print("  ");
30 			else
31 				Print("%02x",*(unsigned char *)(buffer+i));
32 		}
33 		Print("  ");
34 
35 		for(i = start;i < start + DUMPED_BLOCK_SIZE;i++) {
36 			if (i < size) {
37 				char c = *(buffer+i);
38 
39 				if (c < 30)
40 					Print(".");
41 				else
42 					Print("%c",c);
43 			}
44 			else
45 				break;
46 		}
47 		Print("\n");
48 	}
49 }
50 
51 
52 void
53 createFile(int32 num)
54 {
55 	char name[B_FILE_NAME_LENGTH];
56 	sprintf(name,"./_query_test_%ld",num);
57 
58 	BFile file(name,B_CREATE_FILE | B_WRITE_ONLY);
59 }
60 
61 
62 BEntry *
63 getEntry(int32 num)
64 {
65 	char name[B_FILE_NAME_LENGTH];
66 	sprintf(name,"./_query_test_%ld",num);
67 
68 	return new BEntry(name);
69 }
70 
71 
72 status_t
73 waitForMessage(port_id port,const char *string,int32 op,char *name)
74 {
75 	puts(string);
76 
77 	int32 msg;
78 	char buffer[1024];
79 	ssize_t bytes = read_port_etc(port,&msg,buffer,sizeof(buffer),B_TIMEOUT,1000000);
80 	if (op == B_TIMED_OUT && bytes == B_TIMED_OUT) {
81 		puts("  passed, timed out!\n");
82 		return bytes;
83 	}
84 	if (bytes < B_OK) {
85 		printf("-> %s\n\n", strerror(bytes));
86 		return bytes;
87 	}
88 
89 	BMessage message;
90 	if (message.Unflatten(buffer) < B_OK) {
91 		printf("could not unflatten message:\n");
92 		dumpBlock(buffer, bytes);
93 		return B_BAD_DATA;
94 	}
95 
96 	if (message.what != B_QUERY_UPDATE
97 		|| message.FindInt32("opcode") != op) {
98 		printf("Expected what = %x, opcode = %ld, got:", B_QUERY_UPDATE, op);
99 		message.PrintToStream();
100 		putchar('\n');
101 		return message.FindInt32("opcode");
102 	}
103 	puts("  passed!\n");
104 	return op;
105 }
106 
107 
108 int
109 main(int argc,char **argv)
110 {
111 	port_id port = create_port(100, "query port");
112 	printf("port id = %ld\n", port);
113 	printf("  B_ENTRY_REMOVED = %d, B_ENTRY_CREATED = %d\n\n", B_ENTRY_REMOVED, B_ENTRY_CREATED);
114 
115 	dev_t device = dev_for_path(".");
116 	DIR *query = fs_open_live_query(device, "name=_query_test_*", B_LIVE_QUERY, port, 12345);
117 
118 	createFile(1);
119 	waitForMessage(port, "File 1 created:", B_ENTRY_CREATED, "_query_test_1");
120 
121 	createFile(2);
122 	waitForMessage(port, "File 2 created:", B_ENTRY_CREATED, "_query_test_2");
123 
124 	BEntry *entry = getEntry(2);
125 	if (entry->InitCheck() < B_OK) {
126 		fprintf(stderr, "Could not get entry for file 2\n");
127 		fs_close_query(query);
128 		return -1;
129 	}
130 	entry->Rename("_some_other_name_");
131 	waitForMessage(port,"File 2 renamed (should fall out of query):", B_ENTRY_REMOVED, NULL);
132 
133 	entry->Rename("_some_other_");
134 	waitForMessage(port,"File 2 renamed again (should time out):", B_TIMED_OUT, NULL);
135 
136 	entry->Rename("_query_test_2");
137 	waitForMessage(port,"File 2 renamed back (should be added to query):",
138 		B_ENTRY_CREATED, "_query_test_2");
139 
140 	entry->Rename("_query_test_2_and_more");
141 	status_t status = waitForMessage(port,"File 2 renamed (should stay in query, time out):",
142 							B_TIMED_OUT, "_query_test_2_and_more");
143 	if (status == B_ENTRY_REMOVED) {
144 		waitForMessage(port,"Received B_ENTRY_REMOVED, now expecting file 2 to be added again:",
145 			B_ENTRY_CREATED, NULL);
146 	}
147 
148 	entry->Remove();
149 	delete entry;
150 	waitForMessage(port,"File 2 removed:", B_ENTRY_REMOVED, NULL);
151 
152 	entry = getEntry(1);
153 	if (entry->InitCheck() < B_OK) {
154 		fprintf(stderr, "Could not get entry for file 1\n");
155 		fs_close_query(query);
156 		return -1;
157 	}
158 
159 	entry->Rename("_some_other_name_");
160 	waitForMessage(port, "File 1 renamed (should fall out of query):", B_ENTRY_REMOVED, NULL);
161 
162 	entry->Remove();
163 	delete entry;
164 	waitForMessage(port, "File 1 removed (should time out):", B_TIMED_OUT, NULL);
165 
166 	fs_close_query(query);
167 
168 	return 0;
169 }
170 
171